using DG.Tweening;
using LogSystem;
using System;
using System.Collections.Generic;
using UnityEngine;
using Yoozoo.Core.Extensions.Engine;
using Yoozoo.Gameplay.City.AI;
using Yoozoo.Gameplay.RTS;
using Yoozoo.Mars.Got;
using Object = UnityEngine.Object;
using Random = UnityEngine.Random;

namespace Yoozoo.Gameplay.City
{
    public class CityRealAiNpcController : CityRealAiRoleControllerBase
    {
        /// <summary>
        /// NPC加载路径
        /// </summary>
        protected string ModelPath
        {
            get
            {
                string modelName = RoleInfoInfoConfig.model;
                if (modelName == CityRealAiConst.DefaultMainCharacterModelName)
                    modelName = CityRealAiConst.MainCharacterModelName;

                if (string.IsNullOrEmpty(modelName))
                {
                    modelName = CityRealAiConst.DefaultModelName;
                }

                if (CityRealAiConst.EnableGpuSkinning)
                {
                    return string.Format(CityRealAiConst.NpcGpuSkinningPath, modelName);
                }
                return string.Format(CityRealAiConst.NpcPath, modelName);
            }
        }
        
        public int RoleId { get; }
        
        public int RoleTag { get; }

        private int _currentPower;
        public int CurrentPower
        {
            set
            {
                //int temp = _currentPower + value;
                if (value > RoleInfoInfoConfig.init_power)
                {
                    _currentPower = RoleInfoInfoConfig.init_power;
                }
                else
                {
                    _currentPower = value;
                }
            }
            get
            {
                return _currentPower;
            }
        }

        public int RoleClassType => RoleInfoInfoConfig.role_class;
        
        protected Vector3 BirthWorldPos;

        public virtual CityRealNpcType NpcType { get; }

        public CityRealAiNpcInfo ServerRoleInfo;

        protected CityRealAiRoleInfoConfig RoleInfoInfoConfig;

        /// <summary>
        /// 事件树池配置
        /// </summary>
        protected CityRealAiRoleConfig RoleConfig;
        
        public EventDispatch EventDispatch { get; }

        public int areaId;

        public int staffId;

        // 超出数量限制，隐藏雇员的行为树ID
        public int hideStaffTreeId = 0;
        
        /// <summary>
        /// 是否被隐藏起来
        /// </summary>
        public bool IsAlive { get; protected set; }

        public bool IsLoadComplete { get; protected set; }

        private bool _isPause;

        private int _targetRoomId;
        private int _targetRoomIndex;
        protected float _delayFirstStartTime;

        /// <summary>
        /// 指定Tree执行次数
        /// </summary>
        private int _loopTreeIndex;

        /// <summary>
        /// 当前排队所在位置
        /// </summary>
        protected int _waitIndex = -1;
        
        /// <summary>
        /// 当前排队所在队列
        /// </summary>
        protected int _waitQueueIndex = -1;
        public int WaitQueueIndex => _waitQueueIndex;


        /// <summary>
        /// 当前排队时长
        /// </summary>
        protected float _waitTimer = 0;

        /// <summary>
        /// 当前排队状态（正常/微怒/生气）
        /// </summary>
        protected int _queueMoodStage = -1;

        private CityRealEventTreeType _cacheWaitEventTreeType;
        /// <summary>
        /// 当需要进行排队事件树时，缓存当前去房间的目的
        /// </summary>
        private CityRealAiEventTreeConfig _cacheWaitEventTreeConfig;

        /// <summary>
        /// 当前正在执行的事件树
        /// </summary>
        public CityRealAiEventTreeConfig TreeConfig { get; protected set; }

        protected CityRealEventTreeState TreeState;

        /// <summary>
        /// 当前正在执行的事件树类型
        /// </summary>
        public CityRealEventTreeType TreeType { get; protected set; }
        
        /// <summary>
        /// 当前执行的树是否可以被打断
        /// </summary>
        public bool TreeIsInterrupt { get; protected set; }

        /// <summary>
        /// 单次事件执行失败后重新随机的次数，当一个事件树执行完毕后重置，防止持续找不到事件，消耗大量性能。
        /// </summary>
        private int _tryExecuteIndex = 0;

        /// <summary>
        /// 要去的房间
        /// </summary>
        protected CityRealAiRoomManager _moveToRoom;
        
        protected int _curEventIndex;

        public CityAmbientNPCSeeker Seeker;

        public CityRealAiNpcAnimatorEventController AniEventController;

        private List<int> _curBubbleIndexList;

        private List<int> _curConditionIndexList;

        private List<int> _curBreakIndexList;

        private List<int> _curMoveGoodsEventIndexList;

        private List<int> _bubbleIndexList;

        private List<int> _conditionIndexList;

        private List<int> _breakIndexList;
        
        private List<int> _moveGoodsEventIndexList;
        
        // 一次性消费者行为集合
        protected List<Vector2Int> _costRoleTypeList;
        // 已执行的一次性消费者行为集合
        protected List<int> _executedCostRoleType;
        
        // 一次性消费者行为计时器
        protected float _costRoleTypeExecutedTimer;
        // 一次性消费者行为时长
        protected float _costRoleTypeExecuteDuration;
        // 商品计时器
        protected float _commodityTimer;
        // 客人纠纷计时器
        protected float _disputeTimer;
        
        // 通用时间戳 (对美女npc角色来说:记录上次刷新资源的时间戳)
        protected float _timeStamp;

        // 缓存当前可以转换事件的特殊类型。
        protected List<SpecialBreakInfo> _cacheSpecialBreakInfoList;

        // 记录当前转换事件的特殊类型，用以恢复默认事件。
        protected SpecialBreakInfo _curSpecialBreakInfo;
        
        // 一次性消费是否结账
        protected bool _hasExecutedCostTree = false;
        // 消费者的巴士准备离开
        protected bool _customerBusLeave = false;
        
        // 是否是解锁区域表演中
        protected bool _isUnlockPerform = false;

        public bool IsUnlockAreaPerform
        {
            set
            {
                _isUnlockPerform = value;
            }
            get
            {
                return _isUnlockPerform;
            }
        }

        private float _npcLightAniProgress;

        // 自己的根节点
        protected Transform _npcRoot;

        //npc交互物品使用的骨骼点
        private Transform HandRoot;
        //npc身上拿取的物品
        private GameObject HandObj;
        private string HandObjPath;

        private bool _isInPlayTriggerEffect;
        // 事件触发特效
        private GameObject TriggerEffectObj;
        private string TriggerEffectObjPath;
        
        // 超级客人特效
        private GameObject SupperNpcEffectObj;

        // event事件
        private CityRealAiNpcAnimatorEventController.TriggerFixedDelegate _onTriggerFixed;
        private CityRealAiNpcAnimatorEventController.BindBoneDelegate _onBindBone;
        private CityRealAiNpcAnimatorEventController.AddItemDelegate _onAddItem;
        private CityRealAiNpcAnimatorEventController.GetItemDelegate _onGetItem;
        private CityRealAiNpcAnimatorEventController.PutDownItemDelegate _onPutDownItem;
        private CityRealAiNpcAnimatorEventController.DeleteItemDelegate _onDeleteItem;
        private CityRealAiNpcAnimatorEventController.ShowBubbleDelegate _onShowBubble;
        private CityRealAiNpcAnimatorEventController.HideBubbleDelegate _onHideBubble;
        private CityRealAiNpcAnimatorEventController.OnTriggerEffectDelegate _onTriggerEffect;

        private TimerCallback _onDelatyStart;
        private TimerCallback _onDestroyTriggerEffect;
        private TimerCallback _npcLightAnimation;

        private Action eventMoveEndAction;
        private Action eventEndAction;
        private Action waitFailedCompleteAction;
        private Action outCityOutRoomEventEndAction;

        private Tween _tweener;

        public CityRealAiNpcController(int birthContainerId, CityRealAiRoleInfoConfig roleInfoConfig, Vector3 birthWorldPos) : base(birthContainerId)
        {
            _onTriggerFixed = OnTriggerFixed;
            _onBindBone = OnBindBone;
            _onAddItem = OnAddItem;
            _onGetItem = OnGetItem;
            _onPutDownItem = OnPutDownItem;
            _onDeleteItem = OnDeleteItem;
            _onShowBubble = OnShowBubble;
            _onHideBubble = OnHideBubble;
            _onTriggerEffect = OnTriggerEffect;
            _onDelatyStart = OnDelayStart;
            _onDestroyTriggerEffect = OnDestroyTriggerEffect;
            _npcLightAnimation = NpcLightAnimation;
            EventDispatch = new EventDispatch();
            RoleInfoInfoConfig = roleInfoConfig;
            RoleId = roleInfoConfig.role_id;
            RoleTag = roleInfoConfig.role_tag;
            CurrentPower = roleInfoConfig.init_power;
            TreeConfig = _cfgMgr.EmptyEventTreeCfg;
            BirthWorldPos = birthWorldPos;
            _isInPlayTriggerEffect = false;
            IsLoadComplete = false;
            _curSpecialBreakInfo = new SpecialBreakInfo()
            {
                SpecialId = -1,
                Config = _cfgMgr.EmptySpecialConfig,
            };
            
            eventMoveEndAction = EventMoveEnd;
            eventEndAction = EventEnd;
            waitFailedCompleteAction = WaitFailedComplete;
            outCityOutRoomEventEndAction = OutCityOutRoomEventEnd;
        }

        public override void UpdateContainer(CityRealAiContainerManagerBase containerMgr)
        {
            base.UpdateContainer(containerMgr);
            UpdateContainerInfo();
        }

        protected void UpdateSunLight(bool isPlayAni)
        {
            if (model && model.m_gpuAnimator!=null)
            {
                bool isInRoom = Seeker.IsUseRoomNavigate;
                if(_containerMgr!=null && _containerMgr.ContainerId==CityRealAiConst.WallId)
                {
                    isInRoom = false;
                }
                
                // 检测是否有必要更新
                float targetValue = isInRoom ? CityRealAiConst.NpcLightMaxProgress : CityRealAiConst.NpcLightMinProgress;
                if (model.m_gpuAnimator.InRoom == targetValue)
                {
                    return;
                }
                
                if (isPlayAni)
                {
                    if (isInRoom)
                    {
                        _npcLightAniProgress = CityRealAiConst.NpcLightMinProgress;
                    }
                    else
                    {
                        _npcLightAniProgress = CityRealAiConst.NpcLightMaxProgress;
                    }
                    
                    Timers.inst.Add(CityRealAiConst.NpcLightAniUpdateInterval, (int) (CityRealAiConst.NpcLightAniTime / CityRealAiConst.NpcLightAniUpdateInterval), _npcLightAnimation);
                }
                else
                {
                    if (isInRoom)
                    {
                        model.SetInRoom(CityRealAiConst.NpcLightMaxProgress);
                    }
                    else
                    {
                        model.SetInRoom(CityRealAiConst.NpcLightMinProgress);
                    }
                }
            }
        }

        private void NpcLightAnimation(object o)
        {
            var repeat = (int)(CityRealAiConst.NpcLightAniTime / CityRealAiConst.NpcLightAniUpdateInterval);
            var speed = CityRealAiConst.NpcLightMaxProgress / repeat;
            if (Seeker.IsUseRoomNavigate && _containerMgr.ContainerId!=CityRealAiConst.WallId)
            {
                _npcLightAniProgress = Mathf.Min((_npcLightAniProgress + speed), CityRealAiConst.NpcLightMaxProgress);
            }
            else
            {
                _npcLightAniProgress = Mathf.Max((_npcLightAniProgress - speed), CityRealAiConst.NpcLightMinProgress);
            }
            if(model)
                model.SetInRoom(_npcLightAniProgress);
        }
        
        public virtual void UpdateServerRoleInfo(CityRealAiNpcInfo serverRoleInfo)
        {
            ServerRoleInfo = serverRoleInfo;
            IsAlive = ServerRoleInfo.isShow;
        }

        public void UpdateRoleConfig(CityRealAiRoleConfig roleConfig)
        {
            // 清理RoleType中关注的打断事件和交互物事件，防止和结账事件冲突
            _curBubbleIndexList?.Clear();
            _curConditionIndexList?.Clear();
            _curBreakIndexList?.Clear();
            _curMoveGoodsEventIndexList?.Clear();
            
            RoleConfig = roleConfig;
        }

        public void TriggerCustomerBusLeave()
        {
            _customerBusLeave = true;
            
            // 在区域中、在排队或者在移动的npc，直接生气离开
            if (TreeType==CityRealEventTreeType.WaitQueueEventTree || TreeState==CityRealEventTreeState.WaitMoveRoom)
            {
                var queueMoodConfigs = CityRealAiManager.GetInstance().ConfigMgr.QueueMoodConfigs;
                var queueMoodConfig = queueMoodConfigs[queueMoodConfigs.Count - 1];
                CityRealAiManager.GetInstance().HudMgr.OnShowHud(Uid, _roleObj.transform, queueMoodConfig.bubble, queueMoodConfig.bubble_displaytime, queueMoodConfig.bones_bind_bubble);
                // CityRealAiLuaCallCSharpManager.ShowSadEffectBubble(Uid, _roleObj.transform);  // 心碎气泡
                ((CityAreaNpcController)this).ExecuteBackToBus();
            }
            else
            {
                // 房间里的小人，立即结账，然后离开
                if (!_hasExecutedCostTree && (_containerMgr is CityRealAiRoomManager))
                {
                    // 隐藏进度调
                    CityRealAiManager.GetInstance().HudMgr.OnStopProgressBar(Uid);
                    // 隐藏气泡
                    CityRealAiManager.GetInstance().HudMgr.OnHideHud(Uid);

                    // 切到结账事件
                    bool canExecute = RandomExecutePayEventTree();
                    if (canExecute)
                    {
                        _hasExecutedCostTree = true;
                        return;
                    }
                }
                // 房间外的，直接离开
                EndEventTree();
                TryExecuteEventTree();
            }
        }

        public virtual void OnLoadRoleObj(Action completeCallBack=null)
        {
            CityRealAiManager.GetInstance().Pop(ModelPath, asset =>
            {
                var npcMove = GameObject.Instantiate(CityRealAiManager.GetInstance().NpcMoveObjTemplete);
                _npcRoot = npcMove.transform;
                SetNpcRootParent();

                _roleObj = asset;
                _roleObj.SetParent(npcMove.transform);
                _roleObj.transform.localPosition = Vector3.zero;
                _roleObj.transform.localEulerAngles = Vector3.zero;
                Seeker = npcMove.GetOrAddCompoment<CityAmbientNPCSeeker>();

                switch ((CityRealNpcClassType)RoleClassType)
                {
                    // case CityRealNpcClassType.Staff:
                    //     {
                    //         // 防止Seeker将没有寻路网格处的雇员
                    //         if (Seeker.enabled)
                    //         {
                    //             Seeker.enabled = false;
                    //         }
                    //     }
                    //     break;

                    default:
                        {
                            if (!Seeker.enabled)
                            {
                                Seeker.enabled = true;
                            }
                        }
                        break;
                }
                
#if UNITY_EDITOR
                _debugObj = new GameObject("debugObj: " + ModelPath);
                _debugObj.SetParent(npcMove.transform);
#endif

                GameObject animatorObject;
                model = _roleObj.GetComponentInChildren<ModelInstaning>(true);
                if (model)
                {
                    AniEventController = model.GetOrAddCompoment<CityRealAiNpcAnimatorEventController>();
                    model.Init();
                    //var material = model.mat;
                    //if (LightController.lightControllerMap.TryGetValue("cityScene", out var lightController))
                    //    lightController.SetMaterial(material);
                    model.SetCullingCameraMark("City2dCamera;TimelineCamera");

                    var instanceId = model.SetConfig(model.poolKey, 100000, 1);
                    model.SetMainColor(instanceId, Color.white);
                    
                    model.SetPosition(_roleObj.transform.position);
                    model.SetRotation(_roleObj.transform.eulerAngles);
                    model.SetScale(model.localScale, false);
                    
                    model.SetAnimatorEnabled(true);
                    model.SetRendererEnabled(true);
                    // model.SetCullingLayer(CityRealAiManager.GetInstance().LimitShowState ? 0 : LayerMask.NameToLayer("city"));
                    model.SetCullingLayer(CityRealAiConst.NpcShowLayerMask);

                    // if (ModelPath.Contains("CiyNpc_Male_Free_01") ||
                    //     ModelPath.Contains("CiyNpc_Male_Free_02"))
                    // {
                    //     _roleObj.GetOrAddCompoment<CityAiGangSetting>();
                    // }
                }
                else
                {
                    Animator ani = _roleObj.GetComponentInChildren<Animator>(true);
                    AniEventController = ani.GetOrAddCompoment<CityRealAiNpcAnimatorEventController>();
                }
                
                //注册动画事件
                AniEventController.OnTriggerFixed += _onTriggerFixed;
                AniEventController.OnBindBone += _onBindBone;
                AniEventController.OnAddItem += _onAddItem;
                AniEventController.OnGetItem += _onGetItem;
                AniEventController.OnPutDownItem += _onPutDownItem;
                AniEventController.OnDeleteItem += _onDeleteItem;
                AniEventController.OnShowBubble += _onShowBubble;
                AniEventController.OnHideBubble += _onHideBubble;
                AniEventController.OnTriggerEffect += _onTriggerEffect;
                Seeker.SetupSearchPathFailedCallback(SearchPathPartialComplete, SearchPathErrorComplete);
                if (_isPause) // 加载完成，如果在暂停状态，则触发暂停逻辑。
                {
                    OnStop();
                }
                LoadRoleObjComplete();

                IsLoadComplete = true;

                if (completeCallBack != null)
                {
                    completeCallBack.Invoke();
                }
                
            });
            
        }
        
        protected virtual void SearchPathPartialComplete()
        {
            
        }

        protected virtual void SearchPathErrorComplete()
        {
            
        }

        public void SetNpcRootParent()
        {
            if (_npcRoot == null)
            {
                return;
            }
            _npcRoot.SetParent(_containerMgr.RoomRootTran);
        }

        public void SetNpcScale(float scale)
        {
            if (model)
            {
                model.SetScale(scale, false);
            }
            else
            {
                _roleObj.transform.localScale = new Vector3(scale, scale, scale);
            }
        }

        public void ResetNpcScale()
        {
            if (model)
            {
                model.ResetScale();
            }
        }

        protected virtual void LoadRoleObjComplete()
        {
            if (ServerRoleInfo.isSuperCustomer)
            {
                if (SupperNpcEffectObj)
                {
                    return;
                }
                
                CityRealAiManager.GetInstance().Pop(CityRealAiConst.SupperNpcEffectName, asset =>
                {
                    SupperNpcEffectObj = asset;
                    SupperNpcEffectObj.SetParent(_npcRoot.transform, true);
                    SupperNpcEffectObj.transform.localPosition = Vector3.zero;
                    SupperNpcEffectObj.transform.localEulerAngles = Vector3.zero;
                });
            }

            switch ((CityRealNpcClassType)RoleClassType)
            {
                case CityRealNpcClassType.Babe:
                    {
                        if (!CityRealAiManager.GetInstance().HudMgr.IsExistBabeMood(Uid) && CityRealAiCSharpCallLuaManager.IsBabeMoodResCanReceive(RoleId))
                        {
                            CityRealAiManager.GetInstance().HudMgr.OnShowBabeMood(Uid, CityRealAiConst.BubbleBabeMood, _roleObj.transform, CityRealAiConst.BabeMoodResId);
                        }
                    }
                    break;
            }


        }

        public void LoadInteractive(string interactiveName)
        {
            var path = string.Format(CityRealAiConst.InteractivePath, interactiveName);
            CityRealAiManager.GetInstance().Pop(path, asset =>
            {
                if (HandObj)
                {
                    CityRealAiManager.GetInstance().Push(path, asset);
                    return;
                }
                
                HandObjPath = path;
                HandObj = asset;
                HandObj.SetParent(HandRoot, true);
                HandObj.transform.localPosition = Vector3.zero;
                HandObj.transform.localEulerAngles = Vector3.zero;
                var goodsRotateMono = HandObj.GetComponentInChildren<CityRealMoveGoodsMono>();
                if (goodsRotateMono != null && EventDispatch.PointInfo != null)
                {
                    goodsRotateMono.ChangeNodeRotate(false, EventDispatch.PointInfo.EventConfig.bind_positionoffset_id);
                }
#if UNITY_EDITOR
                HandObj.name = $"AI交互物 = {HandObj.name}";
#endif
            });
        }

        public void OnUnlockNpc()
        {
            OnAliveNpc();
        }

        public void OnAliveNpc()
        {
            IsAlive = true;
            if (_roleObj != null)
            {
                _roleObj.SetActive(true);
                TryExecuteEventTree();
            }
        }
        
        protected virtual void UpdateContainerInfo()
        {
            var areaOrRoom = _containerMgr is CityRealAiAreaManager;
            if (RoleConfig.bubble_type.Length > 0)
            {
                if (_curBubbleIndexList == null)
                {
                    _curBubbleIndexList = new List<int>();
                }
                _curBubbleIndexList.Clear();
                for (int bubbleIndex = 0; bubbleIndex < RoleConfig.bubble_type.Length; bubbleIndex++)
                {
                    var factorType = RoleConfig.bubble_type[bubbleIndex];
                    var factorId = (int)factorType.x;
                    if (areaOrRoom)
                    {
                        if (factorId > CityRealAiConst.VirtualGoodsMinId &&
                            factorId <= CityRealAiConst.VirtualGoodsMaxId)
                        {
                            _curBubbleIndexList.Add(bubbleIndex);
                        }
                    }
                    else
                    {
                        if (factorId == _containerMgr.ContainerId)
                        {
                            _curBubbleIndexList.Add(bubbleIndex);
                        }
                    }
                }
            }
            if (RoleConfig.condition_type.Length > 0)
            {
                if (_curConditionIndexList == null)
                {
                    _curConditionIndexList = new List<int>();
                }
                _curConditionIndexList.Clear();
                for (int conditionIndex = 0; conditionIndex < RoleConfig.condition_type.Length; conditionIndex++)
                {
                    var factorType = RoleConfig.condition_type[conditionIndex];
                    var factorId = (int)factorType.x;
                    if (areaOrRoom)
                    {
                        if (factorId > CityRealAiConst.VirtualGoodsMinId &&
                            factorId <= CityRealAiConst.VirtualGoodsMaxId)
                        {
                            _curConditionIndexList.Add(conditionIndex);
                        }
                    }
                    else
                    {
                        if (factorId == _containerMgr.ContainerId)
                        {
                            _curConditionIndexList.Add(conditionIndex);
                        }
                    }
                }
            }
            if (RoleConfig.interactive_type.Length > 0)
            {
                if (_curMoveGoodsEventIndexList == null)
                {
                    _curMoveGoodsEventIndexList = new List<int>();
                }
                _curMoveGoodsEventIndexList.Clear();
                for (int moveGoodsIndex = 0; moveGoodsIndex < RoleConfig.interactive_type.Length; moveGoodsIndex++)
                {
                    var factorType = RoleConfig.interactive_type[moveGoodsIndex];
                    var factorId = (int)factorType.x;
                    if (areaOrRoom)
                    {
                        if (factorId > CityRealAiConst.VirtualGoodsMinId &&
                            factorId <= CityRealAiConst.VirtualGoodsMaxId)
                        {
                            _curMoveGoodsEventIndexList.Add(moveGoodsIndex);
                        }
                    }
                    else
                    {
                        if (factorId == _containerMgr.ContainerId)
                        {
                            _curMoveGoodsEventIndexList.Add(moveGoodsIndex);
                        }
                    }
                }
            }
            if (RoleConfig.break_type.Length > 0)
            {
                if (_curBreakIndexList == null)
                {
                    _curBreakIndexList = new List<int>();
                }
                _curBreakIndexList.Clear();
                for (int breakIndex = 0; breakIndex < RoleConfig.break_type.Length; breakIndex++)
                {
                    var factorType = RoleConfig.break_type[breakIndex];
                    var factorId = (int)factorType.x;
                    if (areaOrRoom)
                    {
                        if (factorId > CityRealAiConst.VirtualGoodsMinId &&
                            factorId <= CityRealAiConst.VirtualGoodsMaxId)
                        {
                            _curBreakIndexList.Add(breakIndex);
                        }
                    }
                    else
                    {
                        if (factorId == _containerMgr.ContainerId)
                        {
                            _curBreakIndexList.Add(breakIndex);
                        }
                    }
                }
            }
        }

        public void OnPause(bool isPause)
        {
            if (_isPause == isPause)
            {
                return;
            }

            _isPause = isPause;
            if (isPause)
            {
                OnStop();
            }
            else
            {
                OnReStart();
            }
        }

        private void OnReStart()
        {
            if (IsAlive && _npcRoot != null)
            {
                _npcRoot.SetActive(true);
                if (model && model.CullingLayer==CityRealAiConst.NpcShowLayerMask)
                {
                    CityRealAiManager.GetInstance().HudMgr.OnReShowHud(Uid);
                    CityRealAiManager.GetInstance().HudMgr.OnReShowSkillHud(Uid);
                    CityRealAiManager.GetInstance().HudMgr.OnReShowProgressBar(Uid);
                    CityRealAiManager.GetInstance().HudMgr.OnReShowCommodity(Uid);
                    CityRealAiManager.GetInstance().HudMgr.OnReShowEffect(Uid);
                    CityRealAiManager.GetInstance().HudMgr.OnReShowStaff(Uid, CityRealAiConst.StaffBubble, _roleObj.transform, 
                            staffId, CityRealAiConst.DefaultBubbleBone);
                    // CityRealAiManager.GetInstance().HudMgr.OnReShowBabeMood(Uid);
                    CityRealAiManager.GetInstance().HudMgr.OnReShowDialogue(Uid);
                }
            }
        }

        private void OnStop()
        {
            if (IsAlive && _npcRoot != null)
            {
                _npcRoot.SetActive(false);
                CityRealAiManager.GetInstance().HudMgr.OnStopHud(Uid);
                CityRealAiManager.GetInstance().HudMgr.OnStopSkillHud(Uid);
                CityRealAiManager.GetInstance().HudMgr.OnStopProgressBar(Uid);
                CityRealAiManager.GetInstance().HudMgr.OnStopCommodity(Uid);
                CityRealAiManager.GetInstance().HudMgr.OnStopStaff(Uid);
                CityRealAiManager.GetInstance().HudMgr.OnStopBabeMood(Uid);
                CityRealAiManager.GetInstance().HudMgr.OnStopEffect(Uid);
                CityRealAiManager.GetInstance().HudMgr.OnStopDialogue(Uid);
            }
        }

        public void ShowOrHide(bool state)
        {
            if (!IsAlive)
            {
                return;
            }
            if (model)
            {
                if (!state)
                {
                    switch ((CityRealNpcClassType)RoleClassType)
                    {
                        case CityRealNpcClassType.Staff:    // 雇员不受LOD影响
                        case CityRealNpcClassType.Babe:     // 美女不受LOD影响
                            return;
                    }
                    
                    //model.SetRendererEnabled(state);
                    model.SetCullingLayer(CityRealAiConst.NpcHideLayerMask);
                    
                    CityRealAiManager.GetInstance().HudMgr.OnHideHud(Uid);
                    CityRealAiManager.GetInstance().HudMgr.OnHideSkillHud(Uid);
                    CityRealAiManager.GetInstance().HudMgr.OnHideProgressBar(Uid);
                    CityRealAiManager.GetInstance().HudMgr.OnHideCommodity(Uid);
                    CityRealAiManager.GetInstance().HudMgr.OnHideStaff(Uid);
                    // CityRealAiManager.GetInstance().HudMgr.OnHideBabeMood(Uid);
                    CityRealAiManager.GetInstance().HudMgr.OnHideEffect(Uid);
                    CityRealAiManager.GetInstance().HudMgr.OnHideDialogue(Uid);
                }
                else
                {
                    //model.SetRendererEnabled(state);
                    model.SetCullingLayer(CityRealAiConst.NpcShowLayerMask);
                    
                    CityRealAiManager.GetInstance().HudMgr.OnReShowHud(Uid);
                    CityRealAiManager.GetInstance().HudMgr.OnReShowSkillHud(Uid);
                    CityRealAiManager.GetInstance().HudMgr.OnReShowProgressBar(Uid);
                    CityRealAiManager.GetInstance().HudMgr.OnReShowCommodity(Uid);
                    CityRealAiManager.GetInstance().HudMgr.OnReShowEffect(Uid);
                    CityRealAiManager.GetInstance().HudMgr.OnReShowStaff(Uid, CityRealAiConst.StaffBubble, _roleObj.transform, 
                                                staffId, CityRealAiConst.DefaultBubbleBone);
                    // CityRealAiManager.GetInstance().HudMgr.OnReShowBabeMood(Uid);
                    CityRealAiManager.GetInstance().HudMgr.OnReShowDialogue(Uid);
                }
            }

            if (HandObj)
            {
                HandObj.SetActive(state);
            }
        }

        public void ShowOrHideByTween(bool state)
        {
            float startValue = state?0:1;
            float endValue = state?1:0;
            if (!IsAlive)
            {
                return;
            }
            if (model)
            {
                if (state)
                {
                    model.SetCullingLayer(CityRealAiConst.NpcShowLayerMask);
                }

                if (_tweener != null)
                {
                    _tweener.Kill();
                    _tweener = null;
                }
                _tweener = DOTween.To(() => startValue, (v) =>
                {
                    model.SetAlpha(v);
                }, endValue, 1f).SetEase(Ease.Linear).OnComplete(()=>{model.SetCullingLayer(state?CityRealAiConst.NpcShowLayerMask:CityRealAiConst.NpcHideLayerMask);});
                
                if (!state)
                {
                    CityRealAiManager.GetInstance().HudMgr.OnHideHud(Uid);
                    CityRealAiManager.GetInstance().HudMgr.OnHideSkillHud(Uid);
                    CityRealAiManager.GetInstance().HudMgr.OnHideProgressBar(Uid);
                    CityRealAiManager.GetInstance().HudMgr.OnHideCommodity(Uid);
                    CityRealAiManager.GetInstance().HudMgr.OnHideStaff(Uid);
                    // CityRealAiManager.GetInstance().HudMgr.OnHideBabeMood(Uid);
                    CityRealAiManager.GetInstance().HudMgr.OnHideEffect(Uid);
                    CityRealAiManager.GetInstance().HudMgr.OnHideDialogue(Uid);
                }
            }
        }

        /// <summary>
        /// 小人呼吸效果
        /// </summary>
        /// <param name="breathLight">0:关闭 1:开启</param>
        public void SetBreathLight(float breathLight)
        {
            if (!IsAlive)
            {
                return;
            }

            if (model)
            {
                model.SetBreathLight(breathLight);
            }
        }

        #region 事件树周期
        public virtual void TryExecuteEventTree(int excludeRoomId = 0)
        {
            _tryExecuteIndex++;
            
            if (!IsAlive)
            {
                return;
            }

#if UNITY_EDITOR
            if (Seeker && Uid == Seeker.DEBUG_UID)
            {
                int aaa = 0;
            }
#endif
            
            // 已有事件树在执行
            if ((TreeState == CityRealEventTreeState.WaitMoveRoom || TreeState ==  CityRealEventTreeState.InProgress) && TreeType != CityRealEventTreeType.IdleEventTree)
            {
                return;
            }

            switch ((CityRealNpcClassType)RoleClassType)
            {
                case CityRealNpcClassType.Customer:
                    {
                        // 顾客执行切换一次性消费行为
                        // // 执行结账行为
                        // if (_costRoleTypeExecutedTimer > _costRoleTypeExecuteDuration && !_hasExecutedCostTree)
                        // {
                        //     bool canExecute = RandomExecutePayEventTree();
                        //     if (canExecute)
                        //     {
                        //         _hasExecutedCostTree = true;
                        //         return;
                        //     }
                        // }
                        // 是否必须返回巴士
                        if (_customerBusLeave)
                        {
                            // 触发返回巴士
                            ((CityAreaNpcController)this).ExecuteBackToBus();
                            return;
                        }
                        
                        // 防止死循环
                        if (_tryExecuteIndex > CityRealAiConst.MaxTryExecuteIndex)
                        {
                            ((CityAreaNpcController)this).ExecuteBackToBus();
                            return;
                        }
                        // 是否可以切换 (第一次执行)
                        if (_executedCostRoleType == null || _executedCostRoleType.Count == 0)
                        {
                            while (ChangeCostRoleType())
                            {
                                // 切换了新的RoleType
                                _costRoleTypeExecutedTimer = 0;
                                _commodityTimer = 0;
                                _disputeTimer = 0;
                                _hasExecutedCostTree = false;
                                // 随机新的行为
                                bool canExecute = RandomExecuteEventTree();
                                if (canExecute)
                                {
                                    // // 记录房间接待时长
                                    // _costRoleTypeExecuteDuration = GetEventTreeRoomReceptionTime();
                                    // 显示想干的事情 (不在当前房间的情况下才显示)
                                    if (!string.IsNullOrEmpty(TreeConfig.consumer_bubble) && TreeConfig.position.y!=_containerMgr.ContainerId)
                                    {
                                        CityRealAiManager.GetInstance().HudMgr.OnShowHud(Uid, _roleObj.transform, TreeConfig.consumer_bubble, -1, CityRealAiConst.DefaultBubbleBone);
                                    }

                                    return;
                                }
                            }
                        }
                        else if(_executedCostRoleType != null && _executedCostRoleType.Count > 0)
                        {
                            // 时间未到，还不可以切换RoleType，继续随机新的行为
                            bool canExecute = RandomExecuteEventTree();
                            if (canExecute)
                            {
                                return;
                            }
                        }
                        
                        // 触发返回巴士
                        ((CityAreaNpcController)this).ExecuteBackToBus();
                        return;
                    }
                    break;
                
                case CityRealNpcClassType.Staff:
                    {
                        // 超出雇员数量限制，隐藏
                        if (hideStaffTreeId > 0)
                        {
                            TreeConfig = _cfgMgr.GetAiEventTreeConfig(hideStaffTreeId);
                            TreeState = CityRealEventTreeState.WaitMoveRoom;
                            switch (hideStaffTreeId)
                            {
                                case CityRealAiConst.FrontStaffHideEventTreeId:
                                    TreeType = CityRealEventTreeType.FrontEmployEventTree;
                                    break;
                                
                                case CityRealAiConst.BackStaffHideEventTreeId:
                                    TreeType = CityRealEventTreeType.UnlockAreaEventTree;
                                    break;
                            }
                            TreeIsInterrupt = TreeConfig.is_interrupt;
                            ExecuteEventTreePosition();
                            return;
                        }
                    }
                    break;
            }
            
            if (_tryExecuteIndex > CityRealAiConst.MaxTryExecuteIndex)
            {
                // TreeConfig = _cfgMgr.GetAiEventTreeConfig(CityRealAiConst.FinallyEventTreeId);
                // TreeState = CityRealEventTreeState.WaitMoveRoom;
                // TreeType = CityRealEventTreeType.IdleEventTree;
                // TreeIsInterrupt = TreeConfig.is_interrupt;
                // ExecuteEventTreePosition();
                RandomExecuteGuarantEventTree();
                return;
            }

            bool isNeedRoomEvent = false;
            // 策划说，在一个房间内也要关注其他房间的特殊事件需不需要自己，所以这个框架结构实际上已经不适用了，还是抛事件比较好一些。
            if (NpcType == CityRealNpcType.RoomNpc)
            {
                if (_containerMgr is CityRealAiRoomManager room)
                {
                    isNeedRoomEvent = room.CheckNeedAndRunNpc(this);
                }
            }
            else
            {
                var areaDic = CityRealAiManager.GetInstance().AreaDic;
                foreach (var keyValuePair in areaDic)
                {
                    var area = keyValuePair.Value;
                    isNeedRoomEvent = area.CheckNeedAndRunNpc(this);
                    if (isNeedRoomEvent)
                    {
                        break;
                    }
                }
            }

            if (!isNeedRoomEvent) // 如果不需要运行房间特殊事件，则开始随机事件
            {
                bool canExecute = RandomExecuteEventTree(excludeRoomId);
                if (canExecute)
                {
                    return;
                }
                
                RandomExecuteIdleEvent(excludeRoomId);
            }
        }
        
        /// <summary>
        /// 获取当前房间接待单个顾客的时长
        /// </summary>
        /// <returns></returns>
        protected float GetEventTreeRoomReceptionTime()
        {
            if (TreeConfig.event_tree_id != _cfgMgr.EmptyEventTreeCfg.event_tree_id)
            {
                if (TreeConfig.position.x == (int)EventExecuteAction.Room)
                {
                    return CityRealAiManager.GetInstance().ConfigMgr.GetRoomReceptionTime((int)TreeConfig.position.y);
                }
            }

            return 0;
        }

        /// <summary>
        /// 检查体力，并运行
        /// </summary>
        /// <param name="id"></param>
        /// <returns>tree 体力足够</returns>
        private bool CheckAndRunRepowerEventTree(ConditionType conditionType, int id, int checkIndex = 0)
        {
            //检查事件前先看下当前的体力，是否可以执行需要的行为
            bool can = CheckPower(conditionType, id);
            //如果体力不够，则执行回复体力池中的事件
            if (!can)
            {
                checkIndex++;
                ExecuteRandomRepowerEvent(checkIndex);
                return false;
            }

            return true;
        }

        /// <summary>
        /// 切换消费者池子
        /// </summary>
        /// <returns></returns>
        public bool ChangeCostRoleType()
        {
            if (_executedCostRoleType == null || _costRoleTypeList == null)
            {
                _executedCostRoleType = new List<int>();
                
                _costRoleTypeList = new List<Vector2Int>();
                // 固定行为
                if (RoleInfoInfoConfig.room_role_type != null)
                {
                    for (int i = 0; i < RoleInfoInfoConfig.room_role_type.Length; i++)
                    {
                        if (RoleInfoInfoConfig.room_role_type[i].x == ServerRoleInfo.buildingId)
                        {
                            _costRoleTypeList.Add(RoleInfoInfoConfig.room_role_type[i]);
                        }
                    }
                }
            }

            if (_costRoleTypeList.Count > 0)
            {
                if (_executedCostRoleType.Count >= _costRoleTypeList.Count)
                {
                    return false;
                }
                
                // 切换RoleType
                {
                    // int index = _executedCostRoleType.Count;
                    
                    // 顺序执行一次，改为随机执行
                    //随机替换成权重
                    var randomList = randomConfigList;
                    randomList.Clear();
                    for (int i = 0; i < _costRoleTypeList.Count; i++)
                    {
                        if (!_executedCostRoleType.Contains((int)_costRoleTypeList[i].y))
                        {
                            randomList.Add(new RandomConfig()
                            {
                                value = i,
                                weight = 100,
                            });
                        }
                    }
                    var cfg = GetRandomValue();
                    // 随机完就清空
                    _executedCostRoleType.Clear();
                    
                    var roleTypeCfg = _costRoleTypeList[cfg.value].y;
                    var roleConfig = CityRealAiManager.GetInstance().ConfigMgr.GetAiRoleConfig((int) roleTypeCfg);
                    if (roleConfig.role_type > 0)
                    {
                        // 切换类型
                        UpdateRoleConfig(roleConfig);
                        _executedCostRoleType.Add(roleConfig.role_type);
                        UpdateContainerInfo();
                        return true;
                    }
                }
                
            }

            return false;
        }
        
        /// <summary>
        /// 执行解锁区域事件
        /// </summary>
        public bool ExecuteUnlockAreaEvent()
        {
            if (RoleConfig.unlock_area_array != null && RoleConfig.unlock_area_array.Length > 0)
            {
                //随机替换成权重
                var randomList = randomConfigList;
                randomList.Clear();
                for (int i = 0; i < RoleConfig.unlock_area_array.Length; i++)
                {
                    randomList.Add(new RandomConfig()
                    {
                        value = i,
                        weight = (int)RoleConfig.unlock_area_array[i].y
                    });
                }
                var cfg = GetRandomValue();
                
                var treeId = RoleConfig.unlock_area_array[cfg.value];
                if (CheckAndRunRepowerEventTree(ConditionType.Tree, (int)treeId.x))
                {
                    TreeConfig = _cfgMgr.GetAiEventTreeConfig((int) treeId.x);
                    TreeState = CityRealEventTreeState.WaitMoveRoom;
                    TreeType = CityRealEventTreeType.UnlockAreaEventTree;
                    TreeIsInterrupt = TreeConfig.is_interrupt;
                    ExecuteEventTreePosition();
                }
                return true;
            }
            
            return false;
        }

        protected void RestartEventTree()
        {
            // 当前不在执行任何行为树
            if (TreeType == CityRealEventTreeType.None)
            {
                return;
            }
            // 排队中，不处理
            if (TreeType == CityRealEventTreeType.WaitQueueEventTree)
            {
                return;
            }
            
            // 记录一下
            var curTreeConfig = TreeConfig;
            var curTreeState = TreeState;
            var curTreeType = TreeType;
            var curTreeIsInterrupt = TreeIsInterrupt;
            // 停掉
            EndEventTree();
            // 重新开始
            TreeConfig = curTreeConfig;
            TreeState = curTreeState;
            TreeType = curTreeType;
            TreeIsInterrupt = curTreeIsInterrupt;
            ExecuteEventTreePosition();
        }
        
        /// <summary>
        /// 执行前门雇员等待雇佣事件
        /// </summary>
        public bool ExecuteFrontEmployEvent()
        {
            if (RoleConfig.employ_front_array != null && RoleConfig.employ_front_array.Length > 0)
            {
                //随机替换成权重
                var randomList = randomConfigList;
                randomList.Clear();
                for (int i = 0; i < RoleConfig.employ_front_array.Length; i++)
                {
                    randomList.Add(new RandomConfig()
                    {
                        value = i,
                        weight = (int)RoleConfig.employ_front_array[i].y
                    });
                }
                var cfg = GetRandomValue();
                
                var treeId = RoleConfig.employ_front_array[cfg.value];
                if (CheckAndRunRepowerEventTree(ConditionType.Tree, (int)treeId.x))
                {
                    TreeConfig = _cfgMgr.GetAiEventTreeConfig((int) treeId.x);
                    TreeState = CityRealEventTreeState.WaitMoveRoom;
                    TreeType = CityRealEventTreeType.FrontEmployEventTree;
                    TreeIsInterrupt = TreeConfig.is_interrupt;
                    ExecuteEventTreePosition();
                }
                return true;
            }
            
            return false;
        }

        /// <summary>
        /// 执行结账事件
        /// </summary>
        /// <returns></returns>
        public bool RandomExecutePayEventTree()
        {
            if (RoleConfig.cost_tree_array != null && RoleConfig.cost_tree_array.Length > 0)
            {
                //随机替换成权重
                var randomList = randomConfigList;
                randomList.Clear();
                for (int i = 0; i < RoleConfig.cost_tree_array.Length; i++)
                {
                    randomList.Add(new RandomConfig()
                    {
                        value = i,
                        weight = (int)RoleConfig.cost_tree_array[i].y
                    });
                }
                var cfg = GetRandomValue();

                var treeId = RoleConfig.cost_tree_array[cfg.value];
                if (CheckAndRunRepowerEventTree(ConditionType.Tree, (int)treeId.x))
                {
                    if (TreeConfig.event_array.Length <= 0)
                    {
                        return false;
                    }
                    
                    // 清理RoleType中关注的打断事件和交互物事件，防止和结账事件冲突
                    _curBubbleIndexList?.Clear();
                    _curConditionIndexList?.Clear();
                    _curBreakIndexList?.Clear();
                    _curMoveGoodsEventIndexList?.Clear();
                    
                    EndEventTree();

                    // 切换结账事件树
                    TreeConfig = _cfgMgr.GetAiEventTreeConfig((int) treeId.x);
                    TreeState = CityRealEventTreeState.WaitMoveRoom;
                    TreeType = CityRealEventTreeType.CostEventTree;
                    TreeIsInterrupt = TreeConfig.is_interrupt;
                    _curEventIndex = 0;
                    
                    // 上个事件的老数据
                    var eventInfo = TreeConfig.event_array[_curEventIndex];
                    var lastOwner = EventDispatch.PointInfo?.Owner;
                    var positionCfg = TreeConfig.position;
                    // 先确定主事件链的交互点
                    var eventId = (int) eventInfo.x;
                    CityRealAiEventPointInfo pointInfo = null;
                    if (lastOwner != null)
                    {
                        pointInfo = lastOwner.GetEventPoint(Uid, eventId, CityRealEventPointState.Idle); // 延续事件树，优先在现在所在交互点中查找
                    }
                    
                    if (pointInfo == null)
                    {
                        ExecuteEventTreePosition();
                    }
                    else
                    {
                        pointInfo.UpdatePerformer(this);
                        EventDispatch.UpdatePointInfo(pointInfo);
    
                        StartEvent();
                    }
                    // CityRealAiLuaCallCSharpManager.ShowHappyEffectBubble(Uid, _roleObj.transform);  // 爱心气泡
                }
                return true;
            }
            return false;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns>是否有事件被执行</returns>
        public bool RandomExecuteEventTree(int excludeRoomId = 0)
        {
            if (RoleConfig.event_tree_array != null && RoleConfig.event_tree_array.Length > 0) // 可主动执行事件树
            {
                //是否是顾客
                var isCustomer = RoleClassType == (int)CityRealNpcClassType.Customer;
                //随机替换成权重
                var randomList = randomConfigList;
                randomList.Clear();
                for (int i = 0; i < RoleConfig.event_tree_array.Length; i++)
                {
                    var treeIdCfg = RoleConfig.event_tree_array[i];
                    
                    if (isCustomer)
                    {
                        // 顾客可消费的条件是建筑等级 > 0
                        var treeConfig = _cfgMgr.GetAiEventTreeConfig((int) treeIdCfg.x);
                        int roomId = (int)treeConfig.position.y;
                        int roomLevel = CityRealAiCSharpCallLuaManager.GetBuildingLevel(roomId, 1);
                        if (roomLevel < 1)
                        {
                            continue;
                        }
                    }
                    
                    if (excludeRoomId > 0)
                    {
                        var treeConfig = _cfgMgr.GetAiEventTreeConfig((int) treeIdCfg.x);
                        if ((int)treeConfig.position.x == (int)EventExecuteAction.Room)
                        {
                            if ((int)treeConfig.position.y != excludeRoomId)
                            {
                                randomList.Add(new RandomConfig()
                                {
                                    value = i,
                                    weight = (int)treeIdCfg.y
                                });
                            }

                            continue;
                        }
                    }

                    randomList.Add(new RandomConfig()
                    {
                        value = i,
                        weight = (int)treeIdCfg.y
                    });
                }
                if(randomList.Count == 0)
                {
                    return false;
                }
                var cfg = GetRandomValue();
                
                var treeId = RoleConfig.event_tree_array[cfg.value];
                if (CheckAndRunRepowerEventTree(ConditionType.Tree, (int)treeId.x))
                {
                    TreeConfig = _cfgMgr.GetAiEventTreeConfig((int) treeId.x);
                    TreeState = CityRealEventTreeState.WaitMoveRoom;
                    TreeType = CityRealEventTreeType.DrivingEventTree;
                    TreeIsInterrupt = TreeConfig.is_interrupt;
                    ExecuteEventTreePosition();
                }
                return true;
            }
            return false;
        }
        
        //随机执行空闲事件
        public bool RandomExecuteIdleEvent(int excludeRoomId = 0)
        {
            if ((TreeState == CityRealEventTreeState.None || TreeState == CityRealEventTreeState.ExecuteFailed) && RoleConfig.idle_event_tree_array.Length > 0)
            {
                //随机替换成权重
                var randomList = randomConfigList;
                randomList.Clear();
                for (int i = 0; i < RoleConfig.idle_event_tree_array.Length; i++)
                {
                    var treeIdCfg = RoleConfig.idle_event_tree_array[i];
                    if (excludeRoomId > 0)
                    {
                        var treeConfig = _cfgMgr.GetAiEventTreeConfig((int) treeIdCfg.x);
                        if ((int)treeConfig.position.x == (int)EventExecuteAction.Room)
                        {
                            if ((int)treeConfig.position.y != excludeRoomId)
                            {
                                randomList.Add(new RandomConfig()
                                {
                                    value = i,
                                    weight = (int)treeIdCfg.y
                                });
                            }

                            continue;
                        }
                    }
                    randomList.Add(new RandomConfig()
                    {
                        value = i,
                        weight = (int)treeIdCfg.y
                    });
                }

                if (randomList.Count == 0)
                {
                    return false;
                }
                var cfg = GetRandomValue();

                var treeId = RoleConfig.idle_event_tree_array[cfg.value];
                if (CheckAndRunRepowerEventTree(ConditionType.Tree, (int)treeId.x))
                {
                    TreeConfig = _cfgMgr.GetAiEventTreeConfig((int) treeId.x);
                    TreeState = CityRealEventTreeState.WaitMoveRoom;
                    TreeType = CityRealEventTreeType.IdleEventTree;
                    TreeIsInterrupt = TreeConfig.is_interrupt;
                    ExecuteEventTreePosition();
                }
                return true;
            }
            return false;
        }
        
        /// <summary>
        /// 随机触发保底事件
        /// </summary>
        /// <param name="excludeRoomId"></param>
        /// <returns></returns>
        public bool RandomExecuteGuarantEventTree(int excludeRoomId = 0)
        {
            if (RoleConfig.guarant_event_tree_array != null && RoleConfig.guarant_event_tree_array.Length > 0) // 可主动执行事件树
            {
                //随机替换成权重
                var randomList = randomConfigList;
                randomList.Clear();
                for (int i = 0; i < RoleConfig.guarant_event_tree_array.Length; i++)
                {
                    var treeIdCfg = RoleConfig.guarant_event_tree_array[i];
                    
                    if (excludeRoomId > 0)
                    {
                        var treeConfig = _cfgMgr.GetAiEventTreeConfig((int) treeIdCfg.x);
                        if ((int)treeConfig.position.x == (int)EventExecuteAction.Room)
                        {
                            if ((int)treeConfig.position.y != excludeRoomId)
                            {
                                randomList.Add(new RandomConfig()
                                {
                                    value = i,
                                    weight = (int)treeIdCfg.y
                                });
                            }

                            continue;
                        }
                    }

                    randomList.Add(new RandomConfig()
                    {
                        value = i,
                        weight = (int)treeIdCfg.y
                    });
                }
                if(randomList.Count == 0)
                {
                    return false;
                }
                var cfg = GetRandomValue();
                
                var treeId = RoleConfig.guarant_event_tree_array[cfg.value];
                if (CheckAndRunRepowerEventTree(ConditionType.Tree, (int)treeId.x))
                {
                    TreeConfig = _cfgMgr.GetAiEventTreeConfig((int) treeId.x);
                    TreeState = CityRealEventTreeState.WaitMoveRoom;
                    TreeType = CityRealEventTreeType.GuarantEventTree;
                    TreeIsInterrupt = TreeConfig.is_interrupt;
                    ExecuteEventTreePosition();
                }
                return true;
            }
            return false;
        }

        /// <summary>
        /// 立即结束任何事件，开始房间特殊召唤事件。
        /// </summary>
        /// <param name="treeId"></param>
        public virtual void ImmediatelyExecuteEventTree(CityRealAiEventTreeConfig treeConfig, CityRealEventTreeType treeType, int targetRoomId, int targetRoomIndex, int loopTreeIndex, float delayStartTime = 0)
        {
            if (_containerMgr.ContainerId == targetRoomId && TreeConfig.event_tree_id == treeConfig.event_tree_id) // 已经在执行这个事件树了，则只设置一下数据。
            {
                _loopTreeIndex = loopTreeIndex;
                _targetRoomId = targetRoomId;
                _targetRoomIndex = targetRoomIndex;
                _delayFirstStartTime = delayStartTime;
                TreeConfig = treeConfig;
                TreeType = treeType;
                TreeIsInterrupt = false;
                return;
            }
            if (TreeState != CityRealEventTreeState.None)
            {
                EndEventTree();
            }
            if (CheckAndRunRepowerEventTree(ConditionType.Tree, treeConfig.event_tree_id))
            {
                _loopTreeIndex = loopTreeIndex;
                _targetRoomId = targetRoomId;
                _targetRoomIndex = targetRoomIndex;
                _delayFirstStartTime = delayStartTime;
                TreeConfig = treeConfig;
                TreeState = CityRealEventTreeState.WaitMoveRoom;
                TreeType = treeType;
                TreeIsInterrupt = false;
                if (Seeker == null) // 如果模型还没加载完成，则缓存配置，在加载完成时调用
                {
                    Debug.LogErrorFormat(LogModule.CityAI, "模型还没加载完成,不能创建");
                    return;
                }

                if (_delayFirstStartTime > 0)
                {
                    Timers.inst.Add(_delayFirstStartTime, 1, _onDelatyStart);
                }
                else
                {
                    ExecuteEventTreePosition();
                }
            }
        }

        private void OnDelayStart(object o)
        {
            ExecuteEventTreePosition();
        }

        public virtual void ImmediatelyCloseEventTree()
        {
            if (TreeType != CityRealEventTreeType.SpecialEventTree)
            {
                return;
            }
            
            _loopTreeIndex = 0;
            EndEventTree();
            TryExecuteEventTree();
        }
        
        protected virtual void ExecuteEventTreePosition()
        {
            bool conditionOrExecuteSuccess = true; // 没填条件时，默认满足条件
            var conditionOr = TreeConfig.condition_or;
            if (conditionOr == null)
            {
                Debug.LogWarningFormat(LogModule.CityAI,"TreeConfig.condition_or  is  null  RoleId = {0}",RoleId,LogLevelType.Always);
            }else if (conditionOr.Length > 0)
            {
                conditionOrExecuteSuccess = false;
                var aiMgr = CityRealAiManager.GetInstance();
                for (int i = 0; i < conditionOr.Length; i++)
                {
                    if ((int)conditionOr[i].x == (int)CityRealEventConditionType.CurrentDailyStage)
                    {
                        if ((int)SetSunorRain.getInstance().Stage == (int)conditionOr[i].y)
                        {
                            conditionOrExecuteSuccess = true;
                            break;
                        }
                    }
                }
            }

            if (!conditionOrExecuteSuccess)
            {
                EndEventTree();
                TryExecuteEventTree();
                return;
            }
            
            var positionCfg = TreeConfig.position;
            var eventInfo = TreeConfig.event_array[_curEventIndex];
            var eventId = (int) eventInfo.x;
            var eventCfg = _cfgMgr.GetAiEventConfig(eventId);
            var isFlashEvent = ((int)eventCfg.goto_speed == -1);
            
            if ((int)positionCfg.x == (int)EventExecuteAction.Room)
            {
                var roomId = (int)positionCfg.y;
                if (roomId == 0) // 房间特殊事件时，可能需要去指定房间，例如：建筑工人，那个房子在升级，他就去那个房间。
                {
                    roomId = _targetRoomId;
                }
            
                if (_containerMgr.ContainerId == roomId) // 在本房间内
                {
                    var navigateAreaType = (int)positionCfg.z;
                    if (navigateAreaType == (int)CityRealRoomNavigateArea.InRoom)
                    {
                        StartEventTree();
                    }
                    else if (navigateAreaType == (int)CityRealRoomNavigateArea.RoomExternal)
                    {
                        if (Seeker.IsUseRoomNavigate)
                        {
                            if (isFlashEvent) // 闪现过去
                            {
                                Seeker.SetIsInRoomAction(false);
                                UpdateSunLight(false);
                                StartEventTree();
                            }
                            else
                            {
                                MoveToRoomExternal();
                            }
                        }
                        else
                        {
                            StartEventTree();
                        }
                    }
                }
                else
                {
                    //寻找房间需要全区域寻找，先在本区域内寻找，如果没有，遍历寻找其他的区域
                    if (_containerMgr is CityRealAiAreaManager areaMgr) // 在区域内，直接进入房间
                    {
                        MoveToRoom(areaMgr, roomId, _targetRoomIndex);
                    }
                    else if (_containerMgr is CityRealAiRoomManager outRoomMgr) // 在房间内，先回到区域内，再进入房间
                    {
                        if (Seeker.IsUseRoomNavigate)
                        {
                            if (isFlashEvent)
                            {
                                OutRoomEventEnd();
                            }
                            else
                            {                           
                                Seeker.InRoomStartMove(Uid, outRoomMgr.AreaId, outRoomMgr.OutRoomLocalPos, eventCfg.goto_speed, outRoomMgr, OutRoomEventEnd);
                            }
                        }
                        else // 已经在房间外部了，直接改变数据归属，开始新的事件树
                        {
                            OutRoomEventEnd();
                        }
                    }
                }
            }
            else if ((int)positionCfg.x == (int)EventExecuteAction.Area)
            {
                if (_containerMgr is CityRealAiAreaManager areaMgr)
                {
                    StartEventTree();
                }
                else if (_containerMgr is CityRealAiRoomManager outRoomMgr)
                {
                    if (isFlashEvent)
                    {
                        OutRoomEventEnd();
                    }
                    else
                    {
                        Seeker.InRoomStartMove(Uid, outRoomMgr.AreaId, outRoomMgr.OutRoomLocalPos, eventCfg.goto_speed, outRoomMgr, OutRoomEventEnd);
                    }
                }
            }
            else if ((int)positionCfg.x == (int)EventExecuteAction.AreaRandom)
            {
                if (_containerMgr is CityRealAiAreaManager areaMgr)
                {
                    StartEventTree();
                }
                else if (_containerMgr is CityRealAiRoomManager outRoomMgr)
                {
                    if (isFlashEvent)
                    {
                        OutRoomEventEnd();
                    }
                    else
                    {
                        Seeker.InRoomStartMove(Uid, outRoomMgr.AreaId, outRoomMgr.OutRoomLocalPos, eventCfg.goto_speed, outRoomMgr, OutRoomEventEnd);
                    }
                }
            }
            else if ((int)positionCfg.x == (int)EventExecuteAction.AreaRandomOnly)
            {
                StartEventTree();

            }
            else if ((int)positionCfg.x == (int)EventExecuteAction.Idle)
            {
                StartEventTree();
            }
            else if ((int)positionCfg.x == (int)EventExecuteAction.BackStaffWaitQueue)
            {
                CityRealAiWallManager wallMgr = CityRealAiManager.GetInstance().GetCityRealAiWallManager();
                CityRealAiEventPointInfo pointInfo = wallMgr.GetBackStaffWaitPointInfo(_waitIndex, eventId);
                if (pointInfo == null)
                {
                    bool bResult = wallMgr.TryStartBackStaffWaitQueue(this, out _waitIndex, out _waitQueueIndex);
                    if (bResult)
                    {
                        pointInfo = wallMgr.GetBackStaffWaitPointInfo(_waitIndex, eventId);
                    }
                }
                if (pointInfo != null)
                {
                    Seeker.InRoomStartMove(Uid, wallMgr.AreaId, pointInfo.PointConfig.Position, eventCfg.goto_speed, wallMgr, StartEventTree);
                }
                else
                {
                    // TODO 隐藏小人
                }
            }
            else if ((int)positionCfg.x == (int)EventExecuteAction.FrontStaffWaitQueue)
            {
                CityRealAiWallManager wallMgr = CityRealAiManager.GetInstance().GetCityRealAiWallManager();
                CityRealAiEventPointInfo pointInfo = wallMgr.GetFrontStaffWaitPointInfo(_waitIndex, eventId);
                if (pointInfo == null)
                {
                    bool bResult = wallMgr.TryStartFrontStaffWaitQueue(this, out _waitIndex, out _waitQueueIndex);
                    if (bResult)
                    {
                        pointInfo = wallMgr.GetFrontStaffWaitPointInfo(_waitIndex, eventId);
                    }
                }
                if (pointInfo != null)
                {
                    Seeker.InRoomStartMove(Uid, wallMgr.AreaId, pointInfo.PointConfig.Position, eventCfg.goto_speed, wallMgr, StartEventTree);
                }
                else
                {
                    // TODO 隐藏小人
                }
            }
        }

        /// <summary>
        /// 去某个房间
        /// </summary>
        /// <param name="area"></param>
        /// <param name="roomId"></param>
        private void MoveToRoom(CityRealAiAreaManager area, int roomId, int roomIndex)
        {
            _moveToRoom = GetRoomByRoomId(area, roomId, roomIndex);
            if (_moveToRoom == null)
            {           
                EndEventTree();
                TryExecuteEventTree(roomId);
                return;
            }

            // if (_moveToRoom.IsDragState || (_moveToRoom.IsInState(CityRealRoomState.Upgrade) && RoleTag != CityRealAiConst.UpgradeNpcTag)) 
            if (_moveToRoom.IsDragState) 
            {
                EndEventTree();
                TryExecuteEventTree(roomId);
                return;
            }
            
            _moveToRoom.AddMoveToSelfNpc(this);
            var positionCfg = TreeConfig.position;
            var navigateAreaType = (int)positionCfg.z;
            if (navigateAreaType == (int)CityRealRoomNavigateArea.InRoom)
            {
                var eventInfo = TreeConfig.event_array[_curEventIndex];
                var eventId = (int) eventInfo.x;
                var eventCfg = _cfgMgr.GetAiEventConfig(eventId);
                
                var isFlashEvent = ((int)eventCfg.goto_speed == -1);
                if (isFlashEvent)
                {
                    InRoomEventEnd();
                }
                else
                {
#if UNITY_EDITOR && ENABLE_CITY_AI_PROFILER
                    Debug.LogFormat(LogModule.CityAI, "Uid = {0} 移动 房间或区域 = {1} eventId = {2} ", LogLevelType.Develop, Uid, _moveToRoom.ContainerId, eventId);
#endif
                    Seeker.InRoomStartMove(Uid, _moveToRoom.ContainerId, _moveToRoom.InRoomLocalPos, eventCfg.goto_speed, _moveToRoom, InRoomEventEnd);
                }
            }
            else if (navigateAreaType == (int)CityRealRoomNavigateArea.RoomExternal)
            {
                var eventInfo = TreeConfig.event_array[_curEventIndex];
                var eventId = (int) eventInfo.x;
                var pointInfo = _moveToRoom.GetEventPointInfo(Uid, eventId, CityRealEventPointState.Idle);
                if (pointInfo == null) // 没有可用的事件点
                {
                    EndEventTree();
                    TryExecuteEventTree(roomId);
                }
                else
                {                
                    var isFlashEvent = ((int)pointInfo.EventConfig.goto_speed == -1);
                    if (isFlashEvent)
                    {
                        OutRoomExternalEventEnd();
                    }
                    else
                    {                   
                        Seeker.InRoomStartMove(Uid, _moveToRoom.ContainerId, pointInfo.PointConfig.Position, pointInfo.EventConfig.goto_speed, _moveToRoom, OutRoomExternalEventEnd);
                    }
                }
            }
        }

        /// <summary>
        /// 属于某个房间，但是在房间外部寻路、干活
        /// </summary>
        private void MoveToRoomExternal()
        {
            if (_containerMgr is CityRealAiRoomManager outRoomMgr)
            {
                var eventInfo = TreeConfig.event_array[_curEventIndex];
                var eventId = (int) eventInfo.x;
                var eventCfg = _cfgMgr.GetAiEventConfig(eventId);
                Seeker.InRoomStartMove(Uid, outRoomMgr.ContainerId, outRoomMgr.OutRoomLocalPos, eventCfg.goto_speed, outRoomMgr, OutRoomExternalEventEnd);
            }
        }

        private void OutRoomExternalEventEnd()
        {
            if (_containerMgr is CityRealAiAreaManager areaMgr) // 如果是从区域进入到房间外部，则只更新数据归属，不切换寻路网格
            {
                _moveToRoom.RemoveMoveToSelfNpc(this);
                areaMgr.RemoveNpcCtrl(RoleId, Uid);
                UpdateContainer(_moveToRoom);
                _moveToRoom.AddNpcCtrl(this);
            }
            Seeker.SetIsInRoomAction(false);
            UpdateSunLight(true);
            StartEventTree();
        }

        private CityRealAiRoomManager GetRoomByRoomId(CityRealAiAreaManager areaMgr, int roomId, int roomIndex)
        {
            CityRealAiRoomManager moveToRoom;
            if (roomIndex > 0)
            {
                moveToRoom = areaMgr.GetRoom(roomId, roomIndex);
            }
            else
            {
                moveToRoom = areaMgr.GetRandomRoom(roomId);
            }
            if (moveToRoom == null)
            {
                var areaDic = CityRealAiManager.GetInstance().AreaDic;
                foreach (var item in areaDic)
                {
                    if (item.Value.ContainerId != areaMgr.ContainerId)
                    {
                        if (roomIndex > 0)
                        {
                            moveToRoom = item.Value.GetRoom(roomId, roomIndex);
                        }
                        else
                        {
                            moveToRoom = item.Value.GetRandomRoom(roomId);
                        }
                        if (moveToRoom != null)
                        {
                            return moveToRoom;
                        }
                    }
                }
            }

            return moveToRoom;
        }

        //小人进入房间的回调
        private void InRoomEventEnd()
        {
            if (_containerMgr is CityRealAiAreaManager areaMgr)
            {
                _moveToRoom.RemoveMoveToSelfNpc(this);
                // if (_moveToRoom.IsDragState || (_moveToRoom.IsInState(CityRealRoomState.Upgrade) && RoleTag != CityRealAiConst.UpgradeNpcTag))
                if (_moveToRoom.IsDragState)
                {
                    EndEventTree();
                    TryExecuteEventTree(_moveToRoom.ContainerId);
                    return;
                }
                
#if UNITY_EDITOR
                if (Seeker && Uid == Seeker.DEBUG_UID)
                {
                    int aaa = 0;
                }
#endif
                // 隐藏气泡
                CityRealAiManager.GetInstance().HudMgr.OnHideHud(Uid);
                
                if (_moveToRoom.IsFull) // 房间已经满了，换一个树执行。
                {
                    if (_moveToRoom.IsCanWait) // 是否还有空位排队
                    {
                        var waitQueueSuccess = _moveToRoom.TryStartWaitQueue(this, out _waitIndex, out _waitQueueIndex);
                        if (waitQueueSuccess)
                        {
                            _cacheWaitEventTreeConfig = TreeConfig;
                            _cacheWaitEventTreeType = TreeType;
                            RandomExecuteWaitEventTree(true);
                        }
                        else
                        {
                            var excludeRoomId = _moveToRoom.ContainerId;
                            _moveToRoom = null;
                            _targetRoomId = 0;
                            _targetRoomIndex = 0;
                            TreeState = CityRealEventTreeState.ExecuteFailed;
                            EndEventTree();
                            TryExecuteEventTree(excludeRoomId);
                        }
                    }
                    else
                    {
                        var excludeRoomId = _moveToRoom.ContainerId;
                        _moveToRoom = null;
                        _targetRoomId = 0;
                        _targetRoomIndex = 0;
                        TreeState = CityRealEventTreeState.ExecuteFailed;
                        EndEventTree();
                        TryExecuteEventTree(excludeRoomId);
                    }
                }
                else
                {
                    var moveToContainerId = _moveToRoom.ContainerId;
                    areaMgr.RemoveNpcCtrl(RoleId, Uid);
                    UpdateContainer(_moveToRoom);
                    Seeker.SetIsInRoomAction(true);
                    if (!_moveToRoom.rendererNpcEnabled) // 进入房间后，如果房间未开启渲染，则隐藏npc
                    {
                        ShowOrHide(false);
                    }
                    _moveToRoom.AddNpcCtrl(this);
                    _moveToRoom = null; // 已经进入
                    _targetRoomId = 0;
                    _targetRoomIndex = 0;
                    if (moveToContainerId != CityRealAiConst.WallId) // 进入城门后，行为触发时机由城门控制
                    {
                        UpdateSunLight(true);
                        StartEventTree();
                    }
                }
            }
        }
        
        //随机执行排队行为
        public bool RandomExecuteWaitEventTree(bool resetWaitTime = false)
        {
            if (resetWaitTime)
            {
                _waitTimer = 0;
                _queueMoodStage = -1;
            }
            if (RoleConfig.waite_tree_array.Length > 0) // 可主动执行事件树
            {
                //随机替换成权重
                var randomList = randomConfigList;
                randomList.Clear();
                for (int i = 0; i < RoleConfig.waite_tree_array.Length; i++)
                {
                    randomList.Add(new RandomConfig()
                    {
                        value = i,
                        weight = (int)RoleConfig.waite_tree_array[i].y
                    });
                }
                var cfg = GetRandomValue();

                var treeId = RoleConfig.waite_tree_array[cfg.value];
                if (CheckAndRunRepowerEventTree(ConditionType.Tree, (int)treeId.x))
                {
                    TreeConfig = _cfgMgr.GetAiEventTreeConfig((int) treeId.x);
                    TreeState = CityRealEventTreeState.WaitMoveRoom;
                    TreeType = CityRealEventTreeType.WaitQueueEventTree;
                    TreeIsInterrupt = TreeConfig.is_interrupt;
                    StartEventTree();
                }
                return true;
            }
            Debug.LogErrorFormat(LogModule.CityAI, LogLevelType.Develop, "RoleType = {0} 的waite_tree_array配置为空", RoleConfig.role_type);
            return false;
        }

        /// <summary>
        /// 继续排队
        /// </summary>
        /// <param name="waitIndex"></param>
        public void NextWaitQueue(int waitIndex)
        {
            _waitIndex = waitIndex;
            RandomExecuteWaitEventTree();
        }

        /// <summary>
        /// 排队结束，进入房间
        /// </summary>
        public void WaitQueueComplete()
        {
            _waitQueueIndex = -1;
            _waitIndex = -1;
            _waitTimer = 0;
            _queueMoodStage = -1;
            // 隐藏气泡
            CityRealAiManager.GetInstance().HudMgr.OnHideHud(Uid);
            // 隐藏心情气泡
            CityRealAiManager.GetInstance().HudMgr.OnHideProgressBar(Uid);
            EndEventTree();
            if (CheckAndRunRepowerEventTree(ConditionType.Tree, _cacheWaitEventTreeConfig.event_tree_id))
            {
                TreeConfig = _cacheWaitEventTreeConfig;
                TreeType = _cacheWaitEventTreeType;
                TreeIsInterrupt = TreeConfig.is_interrupt;
                TreeState = CityRealEventTreeState.WaitMoveRoom;
                if (TreeConfig.event_array.Length <= _curEventIndex)
                {
                    // 容错处理
                    TryExecuteEventTree();
                    return;
                }
                var eventInfo = TreeConfig.event_array[_curEventIndex];
                var eventId = (int) eventInfo.x;
                var eventCfg = _cfgMgr.GetAiEventConfig(eventId);
                Seeker.InRoomStartMove(Uid, _moveToRoom.ContainerId, _moveToRoom.InRoomLocalPos, eventCfg.goto_speed, _moveToRoom, WaitQueueInRoomEventEnd);
            }
        }

        private void WaitQueueInRoomEventEnd()
        {
            if (_containerMgr is CityRealAiAreaManager areaMgr)
            {
                areaMgr.RemoveNpcCtrl(RoleId, Uid);
                UpdateContainer(_moveToRoom);
                _moveToRoom.AddNpcCtrl(this);
                Seeker.SetIsInRoomAction(true);
                if (!_moveToRoom.rendererNpcEnabled) // 进入房间后，如果房间未开启渲染，则隐藏npc
                {
                    ShowOrHide(false);
                }
                UpdateSunLight(true);

                _moveToRoom = null;
                StartEventTree();
            }
        }

        private void OutRoomEventEnd()
        {
            if (_containerMgr is CityRealAiRoomManager outRoomMgr)
            {
                var ins = CityRealAiManager.GetInstance();
                var inArea = ins.GetArea(outRoomMgr.AreaId);
                _containerMgr.RemoveNpcCtrl(RoleId, Uid);
                UpdateContainer(inArea);
                inArea.AddNpcCtrl(this);
                Seeker.SetIsInRoomAction(false);
                if (!outRoomMgr.rendererNpcEnabled) // 从房间内出来时，如果房间内不渲染npc，则开启渲染
                {
                    //到房间外需要判断是否允许显示
                    if (!ins.LimitShowState)
                    {
                        ShowOrHide(true);
                    }
                }
                // 隐藏气泡
                CityRealAiManager.GetInstance().HudMgr.OnHideProgressBar(Uid);
                    
                UpdateSunLight(true);
                var positionCfg = TreeConfig.position;
                if ((int)positionCfg.x == (int)EventExecuteAction.Room)
                {
                    var roomId = (int)TreeConfig.position.y;
                    if (roomId == 0)
                    {
                        roomId = _targetRoomId;
                    }
                    MoveToRoom(inArea, roomId, _targetRoomIndex);
                }
                else if ((int)positionCfg.x == (int)EventExecuteAction.Area)
                {
                    StartEventTree();
                }
                else if ((int)positionCfg.x == (int)EventExecuteAction.AreaRandom)
                {
                    StartEventTree();
                }
            }
        }

        protected virtual void StartEventTree()
        {
            if (TreeConfig.event_array.Length <= 0)
            {
                Debug.LogErrorFormat(LogModule.CityAI, LogLevelType.Develop, "TreeId = {0} 的配置为空", TreeConfig.event_tree_id);
                return;
            }
            
            // 先确定主事件链的交互点
            var eventInfo = TreeConfig.event_array[_curEventIndex];
            var eventId = (int) eventInfo.x;
            CityRealAiEventPointInfo pointInfo = null;
            var realAiMgr = CityRealAiManager.GetInstance();
            if (eventId == realAiMgr.InCityPointInfo.EventId)
            {
                pointInfo = realAiMgr.InCityPointInfo;
            }
            else if (eventId == realAiMgr.OutCityPointInfo.EventId)
            {
                pointInfo = realAiMgr.OutCityPointInfo;
            }
            else
            {
                var positionCfg = TreeConfig.position;
                if ((int)positionCfg.x == (int)EventExecuteAction.Room)
                {
                    if (TreeType == CityRealEventTreeType.WaitQueueEventTree)
                    {
                        pointInfo = _moveToRoom.GetWaitPointInfo(_waitQueueIndex, _waitIndex, eventId);
                    }
                    else
                    {
                        pointInfo = _containerMgr.GetEventPointInfo(Uid, eventId, CityRealEventPointState.Idle);
                    }
                }
                else if ((int)positionCfg.x == (int)EventExecuteAction.Area)
                {
                    pointInfo = GetAreaEventPointInfo((CityRealAiAreaManager)_containerMgr, Uid, eventId, CityRealEventPointState.Idle);
                }
                else if ((int)positionCfg.x == (int)EventExecuteAction.AreaRandom)
                {
                    if (TreeType == CityRealEventTreeType.SerarchPathFailedEventTree)
                    {
                        pointInfo = ((CityRealAiAreaManager)_containerMgr).CreateVirtualGoodsCtrl(Uid, TreeConfig.event_tree_id, eventId, (int)positionCfg.y, _npcRoot.position);
                    }
                    else
                    {
                        pointInfo = CityRealAiManager.GetInstance().CreateAreaVirtualGoodsCtrl(Uid, TreeConfig.event_tree_id, eventId, (int)positionCfg.y);
                    }                        
                    if (pointInfo == null)
                    {
                        Debug.LogErrorFormat(LogModule.CityAI,LogLevelType.Develop, "Uid = {0} RoleType = {1} ContainerId = {2} 创建虚拟事件集失败", Uid, RoleId, _containerMgr.ContainerId);
                        return;
                    }
                }
                else if ((int)positionCfg.x == (int)EventExecuteAction.AreaRandomOnly)
                {
                    if (TreeType == CityRealEventTreeType.SerarchPathFailedEventTree)
                    {
                        pointInfo = ((CityRealAiAreaManager)_containerMgr).CreateVirtualGoodsCtrl(Uid, TreeConfig.event_tree_id, eventId, (int)positionCfg.y, _npcRoot.position);
                    }
                    else
                    {
                        pointInfo = CityRealAiManager.GetInstance().CreateAreaFixedPointCtrl(Uid, TreeConfig.event_tree_id, eventId, (int)positionCfg.y,areaId, _npcRoot.position);
                    }                        
                    if (pointInfo == null)
                    {
                        Debug.LogErrorFormat(LogModule.CityAI,LogLevelType.Develop, "Uid = {0} RoleType = {1} ContainerId = {2} 创建虚拟事件集失败", Uid, RoleId, _containerMgr.ContainerId);
                        return;
                    }
                }
                else if ((int)positionCfg.x == (int)EventExecuteAction.Idle)
                {
                    // 原地的事件没有事件点，直接执行
                    pointInfo = new CityRealAiEventPointInfo();
                    var pointCfg = new CityRealAiEventPointConfig();
                    pointCfg.eventId = eventId;
                    if (_containerMgr!=null && _containerMgr.RoomRootTran!=null)
                    {
                        pointCfg.Position = _containerMgr.RoomRootTran.InverseTransformPoint(_roleObj.transform.position);
                        pointCfg.Rotate = _containerMgr.RoomRootTran.InverseTransformDirection(_roleObj.transform.eulerAngles);
                    }
                    else
                    {
                        pointCfg.Position = _roleObj.transform.position;
                        pointCfg.Rotate = _roleObj.transform.eulerAngles;
                    }
                    pointInfo.UpdatePointCfg(ref pointCfg);
                }
                else if ((int)positionCfg.x == (int)EventExecuteAction.BackStaffWaitQueue)
                {
                    CityRealAiWallManager wallMgr = CityRealAiManager.GetInstance().GetCityRealAiWallManager();
                    pointInfo = wallMgr.GetBackStaffWaitPointInfo(_waitIndex, eventId);
                    if (pointInfo == null)
                    {
                        bool bResult = wallMgr.TryStartBackStaffWaitQueue(this, out _waitIndex, out _waitQueueIndex);
                        if (bResult)
                        {
                            pointInfo = wallMgr.GetBackStaffWaitPointInfo(_waitIndex, eventId);
                        }
                    }
                }
                else if ((int)positionCfg.x == (int)EventExecuteAction.FrontStaffWaitQueue)
                {
                    CityRealAiWallManager wallMgr = CityRealAiManager.GetInstance().GetCityRealAiWallManager();
                    pointInfo = wallMgr.GetFrontStaffWaitPointInfo(_waitIndex, eventId);
                    if (pointInfo == null)
                    {
                        bool bResult = wallMgr.TryStartFrontStaffWaitQueue(this, out _waitIndex, out _waitQueueIndex);
                        if (bResult)
                        {
                            pointInfo = wallMgr.GetFrontStaffWaitPointInfo(_waitIndex, eventId);
                        }
                    }
                }
            }
            
            if (pointInfo == null) // 没有可以执行的事件点
            {
                EndEventTree();
                TryExecuteEventTree();
                return;
            }

            pointInfo.UpdatePerformer(this);
            EventDispatch.UpdatePointInfo(pointInfo);
            
            StartEvent();
        }


        private CityRealAiEventPointInfo GetAreaEventPointInfo(CityRealAiAreaManager area, int uid, int executeEventId, CityRealEventPointState state)
        {
            var eventInfo = _containerMgr.GetEventPointInfo(Uid, executeEventId, CityRealEventPointState.Idle);
            if (eventInfo != null)
            {
                return eventInfo;
            }
            var areaDic = CityRealAiManager.GetInstance().AreaDic;
            foreach (var item in areaDic)
            {
                if (item.Key == area.ContainerId)
                {
                    continue;
                }

                var targetArea = item.Value;
                eventInfo = targetArea.GetEventPointInfo(uid, executeEventId, state);
                if (eventInfo != null) // 要去某个区域做一个区域事件，因为没有进入区域的时机点，所以一确定要去，就把自己注册到目标区域。
                {
                    area.RemoveNpcCtrl(RoleId, Uid);
                    UpdateContainer(targetArea);
                    targetArea.AddNpcCtrl(this);
                    return eventInfo;
                }
            }

            return null;
        }

        public virtual void EndEventTree()
        {
#if UNITY_EDITOR
            if (Seeker && Uid == Seeker.DEBUG_UID)
            {
                int aaa = 0;
            }

#endif
            if (_moveToRoom != null)
            {
                _moveToRoom.RemoveMoveToSelfNpc(this);
            }
            if (TreeConfig.event_tree_id != _cfgMgr.EmptyEventTreeCfg.event_tree_id)
            {
                var positionCfg = TreeConfig.position;
                if ((int)positionCfg.x == (int)EventExecuteAction.AreaRandom)
                {
                    if (_containerMgr is CityRealAiAreaManager area)
                    {                    
                        area.RemoveVirtualGoodsCtrl(Uid, (int) positionCfg.y);
                    }
                }
            }

            TreeConfig = _cfgMgr.EmptyEventTreeCfg;
            _loopTreeIndex = 0;
            TreeState = CityRealEventTreeState.None;
            TreeType = CityRealEventTreeType.None;
            TreeIsInterrupt = true;
            _curEventIndex = 0;
            if (EventDispatch != null && EventDispatch.PointInfo != null)
            {
                // 在排队的NPC事件点，不存在Owner，这里需要判空。
                if (EventDispatch.PointInfo.PointConfig.eventId > 0 && 
                    EventDispatch.PointInfo.Owner != null &&
                    !string.IsNullOrEmpty(EventDispatch.PointInfo.PointConfig.GoodsTriggerName))
                {
                    EventDispatch.PointInfo.Owner.ResetTriggerAnimation();
                }
                EventDispatch.PointInfo.Reset();
                EventDispatch.Reset();
            }

            if (Seeker != null)
            {
                Seeker.OnReset();
            }
        }

        public bool IsFinishEvent()
        {
            if (TreeConfig.event_tree_id == _cfgMgr.EmptyEventTreeCfg.event_tree_id)
            {
                return true;
            }
            
            return _curEventIndex >= TreeConfig.event_array.Length - 1;
        }
        #endregion

        #region 事件周期
        
        protected virtual void StartEvent()
        {
            TreeState = CityRealEventTreeState.InProgress;
            var pointInfo = EventDispatch.PointInfo;
            var isFlashEvent = ((int)pointInfo.EventConfig.goto_speed == -1);
            if (pointInfo.EventConfig.event_type == (int)CityRealEventType.SpecialEvent)
            {
                if (pointInfo.EventConfig.parameter == CityRealAiConst.NpcOutCityTag)
                {
                    if (_containerMgr is CityRealAiAreaManager area)
                    {
                        if (isFlashEvent)
                        {
                            Seeker.UpdatePos(_containerMgr.GetWorldPos(pointInfo.PointConfig.Position));
                        }
                        Seeker.InRoomStartMove(Uid, TreeConfig.event_tree_id, pointInfo.PointConfig.Position, pointInfo.PointConfig.Rotate, _containerMgr, pointInfo.EventConfig, eventMoveEndAction, eventEndAction, waitFailedCompleteAction);
                    }
                    else if (_containerMgr is CityRealAiRoomManager outRoomMgr)
                    {
                        if (isFlashEvent)
                        {
                            Seeker.UpdatePos(_containerMgr.GetWorldPos(outRoomMgr.OutRoomLocalPos));
                        }

                        Seeker.InRoomStartMove(Uid, outRoomMgr.AreaId, outRoomMgr.OutRoomLocalPos, pointInfo.EventConfig.goto_speed, outRoomMgr, outCityOutRoomEventEndAction);
                    }
                }
                else
                {               
                    if (isFlashEvent)
                    {
                        Seeker.UpdatePos(_containerMgr.GetWorldPos(pointInfo.PointConfig.Position));
                    }
                    Seeker.InRoomStartMove(Uid, TreeConfig.event_tree_id, pointInfo.PointConfig.Position, pointInfo.PointConfig.Rotate, _containerMgr, pointInfo.EventConfig, eventMoveEndAction, eventEndAction, waitFailedCompleteAction);
                }
            }
            else
            {
                CityRealAiContainerManagerBase targetContainer;
                if ((int)TreeConfig.position.x == (int)EventExecuteAction.BackStaffWaitQueue
                    || (int)TreeConfig.position.x == (int)EventExecuteAction.FrontStaffWaitQueue)
                {
                    targetContainer = CityRealAiManager.GetInstance().GetCityRealAiWallManager();
                }
                else if (TreeType == CityRealEventTreeType.WaitQueueEventTree)
                {
                    targetContainer = _moveToRoom;
                }
                else
                {
                    targetContainer = _containerMgr;
                }
                if (isFlashEvent)
                {
                    Seeker.UpdatePos(targetContainer.GetWorldPos(pointInfo.PointConfig.Position));
                }
                pointInfo.UpdateState(CityRealEventPointState.Move);
                Seeker.InRoomStartMove(Uid, TreeConfig.event_tree_id, pointInfo.PointConfig.Position, pointInfo.PointConfig.Rotate, targetContainer, pointInfo.EventConfig, eventMoveEndAction, eventEndAction, waitFailedCompleteAction);
            }

            // 事件开始时触发的气泡
            if (pointInfo.EventConfig.bubble_start_type == (int)CityRealEventBubbleStartType.EventStart)
            {
                var eventConfig = EventDispatch.PointInfo.EventConfig;
                ShowEventBubble(ref eventConfig);
            }
        }

        private void WaitFailedComplete()
        {
            EndEventTree();
            TryExecuteEventTree();
        }
        
        private void OutCityOutRoomEventEnd()
        {
            if (_containerMgr is CityRealAiRoomManager outRoomMgr)
            {
                var inArea = CityRealAiManager.GetInstance().GetArea(outRoomMgr.AreaId);
                _containerMgr.RemoveNpcCtrl(RoleId, Uid);
                UpdateContainer(inArea);
                inArea.AddNpcCtrl(this);
                Seeker.SetIsInRoomAction(false);
                if (!outRoomMgr.rendererNpcEnabled) // 从房间内出来时，如果房间内不渲染npc，则开启渲染
                {
                    ShowOrHide(true);
                }
                UpdateSunLight(true);
                _moveToRoom = null;

                var pointInfo = EventDispatch.PointInfo;
                Seeker.InRoomStartMove(Uid, TreeConfig.event_tree_id, pointInfo.PointConfig.Position, pointInfo.PointConfig.Rotate, _containerMgr, pointInfo.EventConfig, eventMoveEndAction, eventEndAction, waitFailedCompleteAction);
            }
        }

        protected virtual void EventMoveEnd()
        {
            var eventCfg = EventDispatch.PointInfo.EventConfig;
            if (eventCfg.clear_bubble == 1) // 清理当前交互物气泡
            {
                if (eventCfg.event_id == CityRealAiConst.FixEventId) // 修复设备事件，模拟修复设备hud点击
                {
                    CityRealAiManager.GetInstance().HudMgr.OnSimulationClickCommodityHUD(EventDispatch.PointInfo.Owner.Uid);
                }
                else if (eventCfg.event_id == CityRealAiConst.RubbishEventId) // 清理垃圾事件，模拟垃圾hud点击。
                {
                    CityRealAiManager.GetInstance().HudMgr.OnSimulationClickCommodityHUD(EventDispatch.PointInfo.Owner.Uid);
                }
                // else // 其他情况是客人纠纷，模拟商品点击。
                // {
                //     CityRealAiManager.GetInstance().HudMgr.OnSimulationClickCommodityHUD(Uid);
                // }
            }
            if (eventCfg.event_type == (int)CityRealEventType.SpecialEvent)
            {
                if (eventCfg.parameter == CityRealAiConst.NpcHideTag ||
                    eventCfg.parameter == CityRealAiConst.NpcOutCityTag)
                {
                    IsAlive = false; // 隐藏事件，截断该事件
                    _roleObj.SetActive(false);
                    CityRealAiManager.GetInstance().HudMgr.OnHideHud(Uid);
                    CityRealAiManager.GetInstance().HudMgr.OnStopProgressBar(Uid);
                }
                else if (eventCfg.parameter == CityRealAiConst.NpcActiveTag ||
                         eventCfg.parameter == CityRealAiConst.NpcInCityTag)
                {
                    IsAlive = true;
                    _roleObj.SetActive(true);
                }
            }
            else
            {
                if (CheckEventCondition())
                {
                    if (EventDispatch.PointInfo.EventConfig.time_type == (int) CityRealEventTimeType.WaitTime)
                    {
                        EventDispatch.PointInfo.UpdateState(CityRealEventPointState.Wait);
                    }
                    else
                    {
                        Seeker.PlayAni();
                        if ((int)EventDispatch.PointInfo.EventConfig.append_type.x == (int)CityRealNpcEffectTriggerType.StartEvent)
                        {
                            OnTriggerEffect();
                        }
                        EventDispatch.PointInfo.UpdateState(CityRealEventPointState.Work);
                    }
                }
                else
                {
                    PassiveBreakEventEnd();
                }
            }
        }

        protected bool CheckEventCondition()
        {
            var conditionList = EventDispatch.PointInfo.EventConfig.condition;
            if (conditionList.Length <= 0)
            {
                return true;
            }
            
            for (int i = 0; i < conditionList.Length; i++)
            {
                var condition = conditionList[i];
                if ((int) condition.x == (int)CityRealEventConditionType.ExistEvent)
                {
                    var eventInfo = EventDispatch.PointInfo.Owner.GetEventPoint(Uid, (int)condition.y, CityRealEventPointState.Work, CityRealEventPointState.Wait);
                    if (eventInfo == null)
                    {
                        return false;
                    }
                }
            }

            return true;
        }

        public virtual void EventEnd()
        {
            _tryExecuteIndex = 0;
            string parameter = null;
            if (EventDispatch.PointInfo != null)
            {
                EventDispatch.PointInfo.UpdateState(CityRealEventPointState.Idle);
                var eventCfg = EventDispatch.PointInfo.EventConfig;
                parameter = eventCfg.parameter;
                //开始执行事件时就改变体力
                //先取消
                CurrentPower += eventCfg.power_change;
                if (!string.IsNullOrEmpty(EventDispatch.PointInfo.PointConfig.GoodsTriggerName))
                {
                    EventDispatch.PointInfo.Owner.ResetTriggerAnimation();
                }
                // 事件结束时触发的气泡
                if (eventCfg.bubble_start_type == (int)CityRealEventBubbleStartType.EventEnd)
                {
                    ShowEventBubble(ref eventCfg);
                }
                
                // if (eventCfg.clear_bubble == 1) // 清理当前交互物气泡
                // {
                //     if (eventCfg.event_id == CityRealAiConst.FixEventId) // 修复设备事件，模拟修复设备hud点击
                //     {
                //         CityRealAiManager.GetInstance().HudMgr.OnSimulationClickCommodityHUD(EventDispatch.PointInfo.Owner.Uid);
                //     }
                //     else if (eventCfg.event_id == CityRealAiConst.RubbishEventId) // 清理垃圾事件，模拟垃圾hud点击。
                //     {
                //         CityRealAiManager.GetInstance().HudMgr.OnSimulationClickCommodityHUD(EventDispatch.PointInfo.Owner.Uid);
                //     }
                //     // else // 其他情况是客人纠纷，模拟商品点击。
                //     // {
                //     //     CityRealAiManager.GetInstance().HudMgr.OnSimulationClickCommodityHUD(Uid);
                //     // }
                // }
            }

            if (TreeConfig.event_tree_id != _cfgMgr.EmptyEventTreeCfg.event_tree_id) // 在执行事件树时，检查执行后果
            {
                var eventInfo = TreeConfig.event_array[_curEventIndex];

                // if (RoleClassType == (int)CityRealNpcClassType.Customer)
                // {
                //     // 打断行为树，去执行消费者结账事件
                //     if (TreeIsInterrupt)
                //     {
                //         if (_costRoleTypeExecutedTimer>_costRoleTypeExecuteDuration && !_hasExecutedCostTree)
                //         {
                //             // 隐藏进度调
                //             CityRealAiManager.GetInstance().HudMgr.OnStopProgressBar(Uid);
                //
                //             // 切到结账事件
                //             bool canExecute = RandomExecutePayEventTree();
                //             if (canExecute)
                //             {
                //                 _hasExecutedCostTree = true;
                //                 return;
                //             }
                //             else
                //             {
                //                 EndEventTree();
                //                 TryExecuteEventTree();
                //             }
                //             return;
                //         }
                //     }
                // }
                
                var breakType = (int) eventInfo.y;
                if (breakType == (int)CityRealEventBreakType.SuccessToNew || breakType == (int) CityRealEventBreakType.SuccessToNewIdle)
                {
                    var lastTreeType = TreeType;
                    var lastOwner = EventDispatch.PointInfo?.Owner;
                    EndEventTree();
                    if (CheckAndRunRepowerEventTree(ConditionType.Tree, (int)eventInfo.z))
                    {
                        TreeConfig = _cfgMgr.GetAiEventTreeConfig((int) eventInfo.z);
                        TreeState = CityRealEventTreeState.WaitMoveRoom;
                        if (breakType == (int)CityRealEventBreakType.SuccessToNewIdle)
                        {
                            TreeType = CityRealEventTreeType.IdleEventTree;
                            TreeIsInterrupt = TreeConfig.is_interrupt;
                        }
                        else
                        {
                            TreeType = lastTreeType;
                            TreeIsInterrupt = TreeConfig.is_interrupt;
                        }
                        
                        var positionCfg = TreeConfig.position;
                        if ((int)positionCfg.x == (int)EventExecuteAction.Room && _containerMgr.ContainerId == (int)positionCfg.y)
                        {
                            if (TreeConfig.event_array.Length <= 0)
                            {
                                Debug.LogErrorFormat(LogModule.CityAI, LogLevelType.Develop, "TreeId = {0} 的配置为空", TreeConfig.event_tree_id);
                                return;
                            }
            
                            // 先确定主事件链的交互点
                            eventInfo = TreeConfig.event_array[_curEventIndex];
                            var eventId = (int) eventInfo.x;
                            CityRealAiEventPointInfo pointInfo = null;
                            if (lastOwner != null)
                            {
                                pointInfo = lastOwner.GetEventPoint(Uid, eventId, CityRealEventPointState.Idle); // 延续事件树，优先在现在所在交互点中查找
                            }
                            if (pointInfo == null)
                            {
                                ExecuteEventTreePosition();
                            }
                            else
                            {
                                pointInfo.UpdatePerformer(this);
                                EventDispatch.UpdatePointInfo(pointInfo);
            
                                StartEvent();
                            }
                        }
                        else
                        {
                            ExecuteEventTreePosition();
                        }
                    }
                    if (!string.IsNullOrEmpty(parameter) && (_containerMgr is CityRealAiRoomManager mgr))
                    {
                        mgr.TryTriggerRoomStateChange(parameter, Uid); // 尝试触发房间特殊状态
                    }
                    return;
                }
            }

            if (IsFinishEvent())
            {
                if (TreeType == CityRealEventTreeType.SpecialEventTree)
                {
                    if (_loopTreeIndex == -1)
                    {
                        var nextTreeCfg = TreeConfig;
                        var nextTreeType = TreeType;
                        var nextTargetRoomId = _targetRoomId;
                        var nextTargetRoomIndex = _targetRoomIndex;
                        var nextLoopTreeIndex = _loopTreeIndex;
                        EndEventTree();
                        ImmediatelyExecuteEventTree(nextTreeCfg, nextTreeType, nextTargetRoomId, nextTargetRoomIndex, nextLoopTreeIndex);
                    }
                    else
                    {
                        _loopTreeIndex--;
                        if (_loopTreeIndex <= 0)
                        {
                            EndEventTree();
                            TryExecuteEventTree();
                        }
                        else
                        {
                            var nextTreeCfg = TreeConfig;
                            var nextTreeType = TreeType;
                            var nextTargetRoomId = _targetRoomId;
                            var nextTargetRoomIndex = _targetRoomIndex;
                            var nextLoopTreeIndex = _loopTreeIndex;
                            EndEventTree();
                            ImmediatelyExecuteEventTree(nextTreeCfg, nextTreeType, nextTargetRoomId, nextTargetRoomIndex, nextLoopTreeIndex);
                        }
                    }
                }
                else if (TreeType == CityRealEventTreeType.WaitQueueEventTree)
                {
                    StartEventTree();
                }
                else
                {
                    EndEventTree();
                    TryExecuteEventTree();
                }
            }
            else
            {
                NextEvent();
            }
            if (!string.IsNullOrEmpty(parameter) && (_containerMgr is CityRealAiRoomManager roomMgr))
            {
                roomMgr.TryTriggerRoomStateChange(parameter, Uid); // 尝试触发房间特殊状态
            }
        }

        private void NextEvent()
        {
            var nextIndex = _curEventIndex + 1;
            var nextEventInfo = TreeConfig.event_array[nextIndex];
            var nextEventId = (int) nextEventInfo.x;
            
            CityRealAiEventPointInfo nextPointInfo = null;
            var realAiMgr = CityRealAiManager.GetInstance();
            if (nextEventId == realAiMgr.InCityPointInfo.EventId)
            {
                nextPointInfo = realAiMgr.InCityPointInfo;
            }
            else if (nextEventId == realAiMgr.OutCityPointInfo.EventId)
            {
                nextPointInfo = realAiMgr.OutCityPointInfo;
            }
            else
            {
                var positionCfg = TreeConfig.position;
                if ((int)positionCfg.x == (int)EventExecuteAction.Room)
                {
                    if (TreeType == CityRealEventTreeType.WaitQueueEventTree)
                    {
                        nextPointInfo = _moveToRoom.GetWaitPointInfo(_waitQueueIndex, _waitIndex, nextEventId);
                    }
                    else
                    {
                        var pointState = CityRealEventPointState.Idle;
                        if (EventDispatch.PointInfo != null)
                        {                        
                            nextPointInfo = EventDispatch.PointInfo.Owner.GetEventPoint(Uid, nextEventId, pointState);
                        }
                        if (nextPointInfo == null) // 下个事件交互点可能发生了变化
                        {
                            nextPointInfo = _containerMgr.GetEventPointInfo(Uid, nextEventId, pointState);
                        }
                    }
                }
                else if ((int)positionCfg.x == (int)EventExecuteAction.BackStaffWaitQueue)
                {
                    var wallMgr = CityRealAiManager.GetInstance().GetCityRealAiWallManager();
                    nextPointInfo = wallMgr.GetBackStaffWaitPointInfo(_waitIndex, nextEventId);
                }
                else if((int)positionCfg.x == (int)EventExecuteAction.FrontStaffWaitQueue)
                {
                    var wallMgr = CityRealAiManager.GetInstance().GetCityRealAiWallManager();
                    nextPointInfo = wallMgr.GetFrontStaffWaitPointInfo(_waitIndex, nextEventId);
                }
                else  if ((int)positionCfg.x == (int)EventExecuteAction.Area ||
                          (int)positionCfg.x == (int)EventExecuteAction.AreaRandom)
                {
                    var pointState = CityRealEventPointState.Idle;
                    if (EventDispatch.PointInfo != null)
                    {
                        nextPointInfo = EventDispatch.PointInfo.Owner.GetEventPoint(Uid, nextEventId, pointState);
                    }
                    if (nextPointInfo == null) // 下个事件交互点可能发生了变化
                    {
                        nextPointInfo = GetAreaEventPointInfo((CityRealAiAreaManager)_containerMgr, Uid, nextEventId, pointState);
                    }
                }
                else  if ((int)positionCfg.x == (int)EventExecuteAction.Idle)
                {
                    // 原地的事件没有事件点，直接执行
                    nextPointInfo = new CityRealAiEventPointInfo();
                    var pointCfg = new CityRealAiEventPointConfig();
                    pointCfg.eventId = nextEventId;
                    if (_containerMgr!=null && _containerMgr.RoomRootTran!=null)
                    {
                        pointCfg.Position = _containerMgr.RoomRootTran.InverseTransformPoint(_roleObj.transform.position);
                        pointCfg.Rotate = _containerMgr.RoomRootTran.InverseTransformDirection(_roleObj.transform.eulerAngles);
                    }
                    else
                    {
                        pointCfg.Position = _roleObj.transform.position;
                        pointCfg.Rotate = _roleObj.transform.eulerAngles;
                    }
                    nextPointInfo.UpdatePointCfg(ref pointCfg);
                }
                else if ((int)positionCfg.x == (int)EventExecuteAction.BackStaffWaitQueue)
                {
                    CityRealAiWallManager wallMgr = CityRealAiManager.GetInstance().GetCityRealAiWallManager();
                    nextPointInfo = wallMgr.GetBackStaffWaitPointInfo(_waitIndex, nextEventId);
                    if (nextPointInfo == null)
                    {
                        bool bResult = wallMgr.TryStartBackStaffWaitQueue(this, out _waitIndex, out _waitQueueIndex);
                        if (bResult)
                        {
                            nextPointInfo = wallMgr.GetBackStaffWaitPointInfo(_waitIndex, nextEventId);
                        }
                    }
                }
                else if ((int)positionCfg.x == (int)EventExecuteAction.FrontStaffWaitQueue)
                {
                    CityRealAiWallManager wallMgr = CityRealAiManager.GetInstance().GetCityRealAiWallManager();
                    nextPointInfo = wallMgr.GetFrontStaffWaitPointInfo(_waitIndex, nextEventId);
                    if (nextPointInfo == null)
                    {
                        bool bResult = wallMgr.TryStartFrontStaffWaitQueue(this, out _waitIndex, out _waitQueueIndex);
                        if (bResult)
                        {
                            nextPointInfo = wallMgr.GetFrontStaffWaitPointInfo(_waitIndex, nextEventId);
                        }
                    }
                }
            }
            
            if (nextPointInfo == null)
            {
                EndEventTree();
                TryExecuteEventTree();
                return;
            }
            
            Seeker.OnReset();
            EventDispatch.PointInfo?.Reset();
            _curEventIndex++;
            nextPointInfo.UpdatePerformer(this);
            EventDispatch.UpdatePointInfo(nextPointInfo);

            if (!CheckEventDemand())
            {
                PassiveBreakEventEnd();
                return;
            }
            
            var isFlashEvent = ((int)nextPointInfo.EventConfig.goto_speed == -1);
            if (nextPointInfo.EventConfig.event_type == (int)CityRealEventType.SpecialEvent)
            {
                if (nextPointInfo.EventConfig.parameter == CityRealAiConst.NpcOutCityTag)
                {
                    if (_containerMgr is CityRealAiAreaManager area)
                    {
                        if (isFlashEvent)
                        {
                            Seeker.UpdatePos(_containerMgr.GetWorldPos(nextPointInfo.PointConfig.Position));
                        }
                        Seeker.InRoomStartMove(Uid, TreeConfig.event_tree_id, nextPointInfo.PointConfig.Position, nextPointInfo.PointConfig.Rotate, _containerMgr, nextPointInfo.EventConfig, eventMoveEndAction, eventEndAction, waitFailedCompleteAction);
                    }
                    else if (_containerMgr is CityRealAiRoomManager outRoomMgr)
                    {
                        if (isFlashEvent)
                        {
                            Seeker.UpdatePos(_containerMgr.GetWorldPos(outRoomMgr.OutRoomLocalPos));
                        }
                        Seeker.InRoomStartMove(Uid, outRoomMgr.AreaId, outRoomMgr.OutRoomLocalPos, nextPointInfo.EventConfig.goto_speed, outRoomMgr, OutCityOutRoomEventEnd);
                    }
                }
                else
                {                        
                    if (isFlashEvent)
                    {
                        Seeker.UpdatePos(_containerMgr.GetWorldPos(nextPointInfo.PointConfig.Position));
                    }
                    Seeker.InRoomStartMove(Uid, TreeConfig.event_tree_id, nextPointInfo.PointConfig.Position, nextPointInfo.PointConfig.Rotate, _containerMgr, nextPointInfo.EventConfig, eventMoveEndAction, eventEndAction, waitFailedCompleteAction);
                }
            }
            else
            {
                CityRealAiContainerManagerBase targetContainer;
                if (TreeType == CityRealEventTreeType.WaitQueueEventTree)
                {
                    targetContainer = _moveToRoom;
                }
                else
                {
                    targetContainer = _containerMgr;
                }
                if (isFlashEvent)
                {
                    Seeker.UpdatePos(targetContainer.GetWorldPos(nextPointInfo.PointConfig.Position));
                }
                nextPointInfo.UpdateState(CityRealEventPointState.Move);
                Seeker.InRoomStartMove(Uid, TreeConfig.event_tree_id, nextPointInfo.PointConfig.Position, nextPointInfo.PointConfig.Rotate, targetContainer, nextPointInfo.EventConfig, eventMoveEndAction, eventEndAction, waitFailedCompleteAction);
            }
            
            // 事件开始时触发的气泡
            if (nextPointInfo.EventConfig.bubble_start_type == (int)CityRealEventBubbleStartType.EventStart)
            {
                var eventConfig = nextPointInfo.EventConfig;
                ShowEventBubble(ref eventConfig);
            }
        }
        
        protected bool CheckEventDemand()
        {
            var conditionList = EventDispatch.PointInfo.EventConfig.demand;
            if (conditionList.Length <= 0)
            {
                return true;
            }
            
            for (int i = 0; i < conditionList.Length; i++)
            {
                var condition = conditionList[i];
                if ((int) condition.x == (int)CityRealEventConditionType.ExistEvent)
                {
                    var eventInfo = EventDispatch.PointInfo.Owner.GetEventPoint(Uid, (int)condition.y, CityRealEventPointState.Work, CityRealEventPointState.Wait);
                    if (eventInfo == null)
                    {
                        return false;
                    }
                }
            }

            return true;
        }
        #endregion

        public override void OnUpdate()
        {
#if UNITY_EDITOR
            if (_debugObj)
            {
                _debugObj.name = $"Uid={Uid}, ExeTimer={_costRoleTypeExecutedTimer}/{_costRoleTypeExecuteDuration} , Queue={_waitQueueIndex}, QIndex={_waitIndex}, IsUseRoomNavigate={Seeker.IsUseRoomNavigate}";
            }

            if (Seeker && Uid==Seeker.DEBUG_UID)
            {
                int aaa = 0;
            }
#endif

            if (!_isPause && _roleObj)
            {
                switch ((CityRealNpcClassType)RoleClassType)
                {
                    case CityRealNpcClassType.Babe:
                        {
                            // 美女
                            if (Time.time - _timeStamp > 60)
                            {
                                _timeStamp = Time.time;
                                if (!CityRealAiManager.GetInstance().HudMgr.IsExistBabeMood(Uid) && CityRealAiCSharpCallLuaManager.IsBabeMoodResCanReceive(RoleId))
                                {
                                    CityRealAiManager.GetInstance().HudMgr.OnShowBabeMood(Uid, CityRealAiConst.BubbleBabeMood, _roleObj.transform, CityRealAiConst.BabeMoodResId);
                                }
                            }
                        }
                        break;
                    
                    case CityRealNpcClassType.DJ:
                        {
                            // DJ
                            if (CityRealAiConst.IsInOpenBusiness)
                            {
                                // 计算进度
                                if (_costRoleTypeExecuteDuration > 0 && _costRoleTypeExecutedTimer >= _costRoleTypeExecuteDuration)
                                {
                                    // 飘钱、重置时间
                                    CityRealAiCSharpCallLuaManager.ShowAutoDJBubbles(Uid, _roleObj.transform);
                                                
                                    _costRoleTypeExecutedTimer = 0;
                                }
                                if (_costRoleTypeExecutedTimer == 0)
                                {
                                    // 消费进度条
                                    _costRoleTypeExecuteDuration = CityRealAiConst.AutoDJDuration;
                                    CityRealAiManager.GetInstance().HudMgr.OnShowProgressBar(Uid, CityRealAiConst.BubbleProgressBar, _costRoleTypeExecuteDuration-_costRoleTypeExecutedTimer, _roleObj.transform);
                                }

                            
                                _costRoleTypeExecutedTimer += CityRealAiConst.UpdateDeltaTime;
                            }
                        }
                        break;
                    
                    case CityRealNpcClassType.Customer:
                        {
                            // 消费者
                            bool isExistCommodityBubble = CityRealAiManager.GetInstance().HudMgr.IsExistCommodityHud(Uid);
                            bool isExistProgressBar = CityRealAiManager.GetInstance().HudMgr.IsExistProgressBar(Uid);
                            bool isExistHud = CityRealAiManager.GetInstance().HudMgr.IsExistHud(Uid);
                            
                            if (_containerMgr is CityRealAiRoomManager && _containerMgr.ContainerId != CityRealAiConst.WallId && !_customerBusLeave)
                            {
                                // 消费中
                                // 计算进度
                                if (_costRoleTypeExecuteDuration > 0 && _costRoleTypeExecutedTimer >= _costRoleTypeExecuteDuration)
                                {
                                    // 飘钱、重置时间
                                    if (!isExistCommodityBubble && !isExistHud)
                                    {
                                        CityRealAiCSharpCallLuaManager.ShowAutoCustomBubbles(Uid, _roleObj.transform, _containerMgr.ContainerId);
                                    }
                                                
                                    _costRoleTypeExecutedTimer = 0;
                                }
                                if (_costRoleTypeExecutedTimer == 0)
                                {
                                    // 消费进度条
                                    _costRoleTypeExecuteDuration = Random.Range(
                                        CityRealAiConst.AutoCustomDuration - CityRealAiConst.AutoCustomRange,
                                        CityRealAiConst.AutoCustomDuration + CityRealAiConst.AutoCustomRange);
                                }
                                // 控制进度显隐（与交互气泡互斥）
                                if (CityRealAiConst.CanShowAutoCustomProgressBar && !isExistCommodityBubble && !isExistProgressBar)
                                {
                                    CityRealAiManager.GetInstance().HudMgr.OnShowProgressBar(Uid, CityRealAiConst.BubbleProgressBar, _costRoleTypeExecuteDuration-_costRoleTypeExecutedTimer, _roleObj.transform);
                                }
                                else if(isExistCommodityBubble || !CityRealAiConst.CanShowAutoCustomProgressBar)
                                {
                                    CityRealAiManager.GetInstance().HudMgr.OnHideProgressBar(Uid);
                                }
                                
                                _costRoleTypeExecutedTimer += CityRealAiConst.UpdateDeltaTime;
                            }
                            
                            if (TreeState == CityRealEventTreeState.InProgress)
                            {
                                switch (TreeType)
                                {
                                    case CityRealEventTreeType.DrivingEventTree:
                                    case CityRealEventTreeType.MoveGoodsTriggerEventTree:
                                    case CityRealEventTreeType.BubbbleSpecialTree:
                                        {
                                            // 手动营业中，大厅的消费者，触发商品气泡，触发客人纠纷气泡。
                                            if (CityRealAiConst.CanShowCommodityBubble && CityRealAiConst.IsInOpenBusiness && ((CityAreaNpcController)this).BusinessType==CityBusinessType.Manual && _containerMgr.ContainerId == CityRealAiConst.HallId)
                                            {
                                                _commodityTimer += CityRealAiConst.UpdateDeltaTime;
                                                _disputeTimer += CityRealAiConst.UpdateDeltaTime;
                                                if (_commodityTimer >= CityRealAiConst.CommodityRefreshDuration)
                                                {
                                                    _commodityTimer -= CityRealAiConst.CommodityRefreshDuration;
                                                    // 不存在商品hud，且触发概率成功
                                                    if (!isExistCommodityBubble && CityRealAiManager.GetInstance().CheckCommodityBubblePerlimit() && Random.Range(0, 100) <= CityRealAiConst.CommodityBubbleProbability)
                                                    {
                                                        CityRealAiManager.GetInstance().HudMgr.OnShowCommodity(Uid, CityRealAiConst.CommodityBubble, _roleObj.transform, CityRealAiConst.DefaultBubbleBone, isSuperCustomer:ServerRoleInfo.isSuperCustomer);
                                                        CityRealAiManager.GetInstance().AddCommodityBubbleCount();
                                                        TryTriggerSpecial(CityRealAiConst.CommoditySpecialId);
                                                    }
                                                }

                                                if (_disputeTimer >= _cfgMgr.GlobalCfg.city_operate_dispute_pertime)
                                                {
                                                    _disputeTimer -= _cfgMgr.GlobalCfg.city_operate_dispute_pertime;
                                                    if (!isExistCommodityBubble && Random.Range(0, 100) <= _cfgMgr.GlobalCfg.city_operate_dispute_trigger_basepro)
                                                    {
                                                        var disputeCfg = _cfgMgr.GetOperateInteractiveConfig(CityRealAiConst.DisputeCfgId);
                                                        CityRealAiManager.GetInstance().HudMgr.OnShowCommodity(Uid, CityRealAiConst.CommodityBubbleDispute, _roleObj.transform, CityRealAiConst.DefaultBubbleBone, disputeCfg.bubble_id, ServerRoleInfo.isSuperCustomer);
                                                        TryTriggerSpecial(CityRealAiConst.DisputeSpecialId);
                                                    }
                                                }
                                            }
                                            else if (!CityRealAiConst.CanShowCommodityBubble && isExistCommodityBubble)
                                            {
                                                // 当前状态不允许显示交互气泡
                                                CityRealAiManager.GetInstance().HudMgr.OnHideCommodity(Uid);
                                            }
                                        }
                                        break;

                                    case CityRealEventTreeType.WaitQueueEventTree:
                                        {
                                            // 排队中
                                            if (Seeker.aiPath.isStopped)
                                            {
                                                _waitTimer += CityRealAiConst.UpdateDeltaTime;
                                            
                                                // 判断当前排队状态（正常/微怒/生气）
                                                var queueMoodConfigs = CityRealAiManager.GetInstance().ConfigMgr.QueueMoodConfigs;
                                                int startIndex = _queueMoodStage >= 0 ? _queueMoodStage+1 : 0;
                                                for (int i=startIndex; i<queueMoodConfigs.Count; ++i)
                                                {
                                                    if (_waitTimer >= queueMoodConfigs[i].wait_time)
                                                    {
                                                        _queueMoodStage = i;
                                                        if (queueMoodConfigs[i].isdisplay)
                                                        {
                                                            var queueMoodConfig = queueMoodConfigs[i];
                                                            if (queueMoodConfig.display_progress == 1)
                                                            {
                                                                // 心情进度条
                                                                CityRealAiManager.GetInstance().HudMgr.OnShowProgressBar(Uid, queueMoodConfig.bubble, queueMoodConfig.bubble_displaytime, _roleObj.transform, queueMoodConfig.bones_bind_bubble);
                                                            }
                                                            else
                                                            {
                                                                // 心情气泡
                                                                CityRealAiManager.GetInstance().HudMgr.OnShowHud(Uid, _roleObj.transform, queueMoodConfig.bubble, queueMoodConfig.bubble_displaytime, queueMoodConfig.bones_bind_bubble);
                                                            }
                                                        }
                                                        break;
                                                    }
                                                }
                                            
                                                // 如果在最后一个阶段，就返回巴士
                                                if (_queueMoodStage >= queueMoodConfigs.Count - 1)
                                                {
                                                    // CityRealAiLuaCallCSharpManager.ShowSadEffectBubble(Uid, _roleObj.transform);  // 心碎气泡
                                                    // ((CityAreaNpcController)this).ExecuteBackToBus();
                                                    
                                                    // 从排队队列中移除
                                                    if (_moveToRoom != null)
                                                    {
                                                        _moveToRoom.TriggerWaitQueueLeave(this);
                                                    }
                                                    
                                                    CityRealAiManager.GetInstance().HudMgr.OnHideProgressBar(Uid);
                                                    CityRealAiManager.GetInstance().HudMgr.OnHideCommodity(Uid);
                                                    EndEventTree();
                                                    _moveToRoom = null;
                                                    // 触发新的行为
                                                    TryExecuteEventTree();
                                                    return;
                                                }
                                            }
                                        }
                                        break;
                                }
                            }
                        }
                        break;
                }
            }
            
            if (TreeState == CityRealEventTreeState.InProgress && TreeIsInterrupt)
            {
                // 检查关注的气泡
                var bubbleExecuteSuccess = CheckBubbleEventList();
                if (bubbleExecuteSuccess)
                {
                    return;
                }
                
                //检查关注的事件
                var conditionExecuteSuccess = CheckConditionEventList();
                if (conditionExecuteSuccess)
                {
                    return;
                }
                
                //检查关注的打断事件
                var breakExecuteSuccess = CheckBreakEventList();
                if (breakExecuteSuccess)
                {
                    return;
                }

                // 检查关注的交互物
                var moveGoodsExecuteSuccess = CheckMoveGoodsEvent();
                if (moveGoodsExecuteSuccess)
                {
                    return;
                }
            }
        }

        /// <summary>
        /// 触发商品气泡引发的特殊事件
        /// </summary>
        /// <param name="specialId"></param>
        public void TryTriggerSpecial(int specialId, int additionValue = 0, bool killOtherBubble = false)
        {
            var specialGroupId = TreeConfig.specialevent_group;
            if (specialGroupId <= 0)
            {
                return;
            }
            
            var specialCfg = _cfgMgr.GetSpecialConfig(specialId);
            if (specialCfg.id == _cfgMgr.EmptySpecialConfig.id)
            {
                return;
            }
            
            if (_cacheSpecialBreakInfoList == null)
            {
                _cacheSpecialBreakInfoList = new List<SpecialBreakInfo>();
            }
            _cacheSpecialBreakInfoList.Add(new SpecialBreakInfo()
            {
                SpecialId = specialId,
                SpecialGroupId = specialGroupId,
                Config = specialCfg,
                AdditionValue = additionValue,
                KillOtherBubble = killOtherBubble,
            });
            _cacheSpecialBreakInfoList.Sort(SpecialBreakPrioritySort);
            if (_curSpecialBreakInfo.SpecialId == _cacheSpecialBreakInfoList[0].SpecialId) // 不存在优先级更高的特殊事件，则只缓存事件。
            {
                return;
            }

            _curSpecialBreakInfo = _cacheSpecialBreakInfoList[0];
            TriggerSpecial();
        }

        private void TriggerSpecial()
        {
            var treeId = -1;

            for (int i = 0; i < _curSpecialBreakInfo.Config.interrupt_event_tree.Count; i++)
            {
                if (_curSpecialBreakInfo.Config.interrupt_event_tree[i].x == TreeConfig.specialevent_group)
                {
                    treeId = _curSpecialBreakInfo.Config.interrupt_event_tree[i].y;
                    break;
                }
            }

            if (_curSpecialBreakInfo.KillOtherBubble)
            {
                CityRealAiManager.GetInstance().HudMgr.OnHideHud(Uid);
                CityRealAiManager.GetInstance().HudMgr.OnHideCommodity(Uid);
            }
            
            if (treeId > 0)
            {
                var treeConfig = _cfgMgr.GetAiEventTreeConfig(treeId);
                var eventCfg = treeConfig.event_array[0];
                var eventId = (int)eventCfg.x;
                CityRealAiEventPointInfo pointInfo = null;
                if (EventDispatch.PointInfo != null && EventDispatch.PointInfo.Owner != null)
                {
                    pointInfo = EventDispatch.PointInfo.Owner.GetEventPoint(Uid, eventId, CityRealEventPointState.Idle);
                }
                else
                {
                    pointInfo = _containerMgr.GetEventPointInfo(Uid, eventId, CityRealEventPointState.Idle);
                }

                if (pointInfo != null)
                {
                    EndEventTree();
                    TreeConfig = treeConfig;
                    TreeState = CityRealEventTreeState.InProgress;
                    TreeType = CityRealEventTreeType.BubbbleSpecialTree;
                    TreeIsInterrupt = false;
                    pointInfo.UpdatePerformer(this);
                    pointInfo.UpdateState(CityRealEventPointState.Move);
                    EventDispatch.UpdatePointInfo(pointInfo);
                    EventDispatch.UpdatePerformerPointInfo(pointInfo);
                    Seeker.InRoomStartMove(Uid, TreeConfig.event_tree_id, pointInfo.PointConfig.Position, pointInfo.PointConfig.Rotate, _containerMgr, pointInfo.EventConfig, eventMoveEndAction, eventEndAction, waitFailedCompleteAction);
                }
            }

            TriggerSpecialBindFunc(_curSpecialBreakInfo.Config, _curSpecialBreakInfo.AdditionValue);
        }

        private void TriggerSpecialBindFunc(CityRealAiSpecialConfig specialCfg, int additionValue)
        {
            if (specialCfg.bind_func_type.x == 1)
            {
                switch (specialCfg.bind_func)
                {
                    case "func_npc_fire":
                        {
                            CityRealAiManager.GetInstance().HudMgr.OnShowSkillHud(Uid, _roleObj.transform, CityRealAiConst.LightPassionBubble, specialCfg.bind_func_type.y, CityRealAiConst.DefaultBubbleBone, 0, string.Empty, additionValue);
                            // CityRealAiManager.GetInstance().HudMgr.OnShowEffect(Uid, _roleObj.transform, CityRealAiConst.CustomerBurnEffect, 6f, CityRealAiConst.DefaultEffectBone);
                        }
                        break;
                    case "func_npc_addpay":
                        {
                            CityRealAiManager.GetInstance().HudMgr.OnShowEffect(Uid, _roleObj.transform, CityRealAiConst.CustomerTipEffect, 1, CityRealAiConst.DefaultEffectBone);
                        }
                        break;
                }
            }
        }

        private int SpecialBreakPrioritySort(SpecialBreakInfo info1, SpecialBreakInfo info2)
        {
            return -info1.Config.priority.CompareTo(info2.Config.priority);
        }

        public void TriggerSpecialRecover(int specialId)
        {
            if (_cacheSpecialBreakInfoList != null)
            {
                // 先 remove 掉当前数据
                var removeIndex = -1;
                for (int i = 0; i < _cacheSpecialBreakInfoList.Count; i++)
                {
                    if (_cacheSpecialBreakInfoList[i].SpecialId == specialId)
                    {
                        removeIndex = i;
                        break;
                    }
                }

                if (removeIndex >= 0)
                {
                    _cacheSpecialBreakInfoList.RemoveAt(removeIndex);
                }

                if (specialId != _curSpecialBreakInfo.SpecialId) // 不是当前执行的事件，则只移除数据。
                {
                    return;
                }

                if (_cacheSpecialBreakInfoList.Count > 0)
                {
                    _curSpecialBreakInfo = _cacheSpecialBreakInfoList[0]; // 此处，在第一次触发缓存是，就已经排过顺序了，所以第一个一定是优先级最高的。
                    TriggerSpecial();
                    return;
                }
            }

            var specialGroupId = _curSpecialBreakInfo.SpecialGroupId;
            _curSpecialBreakInfo = new SpecialBreakInfo()
            {
                SpecialId = -1,
                Config = _cfgMgr.EmptySpecialConfig,
            };
            var specialCfg = _cfgMgr.GetSpecialRecoverConfig(specialGroupId);
            if (specialCfg.id == _cfgMgr.EmptySpecialRecoverConfig.id)
            {
                TryExecuteEventTree();
                return;
            }
            
            var treeConfig = _cfgMgr.GetAiEventTreeConfig(specialCfg.recover_tree);
            var eventCfg = treeConfig.event_array[0];
            var eventId = (int)eventCfg.x;
            CityRealAiGoodsController lastOwner = null;
            if (EventDispatch.PointInfo != null && EventDispatch.PointInfo.Owner != null) // 恢复事件，优先从所在交互物中获取。
            {
                lastOwner = EventDispatch.PointInfo.Owner;
            }
            EndEventTree();
            
            CityRealAiEventPointInfo pointInfo = null;
            if (lastOwner != null)
            {
                pointInfo = lastOwner.GetEventPoint(Uid, eventId, CityRealEventPointState.Idle);
            }
            else
            {
                pointInfo = _containerMgr.GetEventPointInfo(Uid, eventId, CityRealEventPointState.Idle);
            }

            if (lastOwner != null)
            {
                for (int i = 0; i < lastOwner.EventPointList.Count; i++)
                {
                    var performer = lastOwner.EventPointList[i].Performer;
                    if (performer != null)
                    {
                        performer.EndEventTree();
                        performer.TryExecuteEventTree();
                    }
                }
            }

            if (pointInfo != null)
            {
                TreeConfig = treeConfig;
                TreeState = CityRealEventTreeState.InProgress;
                TreeType = CityRealEventTreeType.DrivingEventTree;
                TreeIsInterrupt = TreeConfig.is_interrupt;
                pointInfo.UpdatePerformer(this);
                pointInfo.UpdateState(CityRealEventPointState.Move);
                EventDispatch.UpdatePointInfo(pointInfo);
                EventDispatch.UpdatePerformerPointInfo(pointInfo);
                Seeker.InRoomStartMove(Uid, TreeConfig.event_tree_id, pointInfo.PointConfig.Position, pointInfo.PointConfig.Rotate, _containerMgr, pointInfo.EventConfig, eventMoveEndAction, eventEndAction, waitFailedCompleteAction);
            }
            else
            {
                TryExecuteEventTree();
            }
        }

        private bool CheckBubbleEventList()
        {
            if (_curBubbleIndexList != null && _curBubbleIndexList.Count > 0)
            {
                InitBubbleEvent();
                
                for (int i = 0; i < _curBubbleIndexList.Count; i++)
                {
                    var bubbleIndex = _curBubbleIndexList[i];
                    var config = RoleConfig.bubble_event_array[bubbleIndex];
                    var bubbleEvnntInfo = _containerMgr.GetCommodityBubbleEventInfo((int)config.x);
                    if (bubbleEvnntInfo == null) // 关注气泡为空，则跳过。
                    {
                        continue;
                    }
                    
                    if (TreeType == CityRealEventTreeType.RepowerEventTree)
                    {
                        bool can = CheckPower((ConditionType)config.y, (int)config.z);
                        if (can)
                        {
                            _bubbleIndexList.Add(bubbleIndex);
                        }
                    }
                    else
                    {
                        _bubbleIndexList.Add(bubbleIndex);
                    }
                }

                if (_bubbleIndexList.Count > 0)
                {
                    var totalWeight = 0;
                    for (int i = 0; i < _bubbleIndexList.Count; i++)
                    {
                        var index = _bubbleIndexList[i];
                        totalWeight += RoleConfig.bubble_weight[index];
                    }

                    int bubbleIndex = 0;
                    int cursor = 0;
                    int random = Random.Range(0, totalWeight);
                    for (int i = 0; i < _bubbleIndexList.Count; i++)
                    {
                        var index = _bubbleIndexList[i];
                        cursor += RoleConfig.bubble_weight[index];
                        if(cursor > random)
                        {
                            bubbleIndex = index;
                            break;
                        }
                    }
                    
                    var config = RoleConfig.bubble_event_array[bubbleIndex];
                    if (!CheckAndRunRepowerEventTree((ConditionType)config.y, (int)config.z))
                    {
                        return true;
                    }
                    var bubblePointInfo = _containerMgr.GetCommodityBubbleEventInfo((int)config.x);

                    CityRealAiEventTreeConfig treeConfig = _cfgMgr.EmptyEventTreeCfg;
                    CityRealAiEventPointInfo pointInfo = null;
                    //类型区分，一为事件二为树
                    if ((ConditionType)config.y == ConditionType.Event)
                    {
                        pointInfo = bubblePointInfo.Owner.GetEventPoint(Uid, (int) config.z, CityRealEventPointState.Idle);
                    }
                    else if ((ConditionType)config.y == ConditionType.Tree)
                    {
                        treeConfig = _cfgMgr.GetAiEventTreeConfig((int) config.z);
                        if (treeConfig.event_tree_id == _cfgMgr.EmptyEventTreeCfg.event_tree_id || treeConfig.event_array.Length <= 0)
                        {
                            return false;
                        }

                        var eventInfo = treeConfig.event_array[0];
                        var eventId = (int) eventInfo.x;
                        pointInfo = bubblePointInfo.Owner.GetEventPoint(Uid, eventId, CityRealEventPointState.Idle);
                    }
                    
                    if (pointInfo != null)
                    {
                        EndEventTree();
                        TreeConfig = treeConfig;
                        TreeState = CityRealEventTreeState.InProgress;
                        TreeType = CityRealEventTreeType.BubbleEventTree;
                        TreeIsInterrupt = false;
                        pointInfo.UpdatePerformer(this);
                        pointInfo.UpdateState(CityRealEventPointState.Move);
                        EventDispatch.UpdatePointInfo(pointInfo);
                        EventDispatch.UpdatePerformerPointInfo(bubblePointInfo);
                        bubblePointInfo.Performer.UpdateCommodityHudPerformer(Uid);
                        Seeker.InRoomStartMove(Uid, TreeConfig.event_tree_id, pointInfo.PointConfig.Position, pointInfo.PointConfig.Rotate, _containerMgr, pointInfo.EventConfig, BubbleEventEnd, eventEndAction, waitFailedCompleteAction);
                        return true;
                    }
                }
            }

            return false;
        }

        private void BubbleEventEnd()
        {
            eventMoveEndAction.Invoke();
            
            if (EventDispatch.PerformerPointInfo != null && EventDispatch.PerformerPointInfo.Performer != null)
            {
                var performer = EventDispatch.PerformerPointInfo.Performer;
                CityRealAiManager.GetInstance().HudMgr.OnSimulationClickCommodityHUD(performer.Uid);
            }
            // EventEnd();
        }

        private void InitBubbleEvent()
        {
            if (_bubbleIndexList == null)
            {
                _bubbleIndexList = new List<int>();
            }
            else
            {
                if (_bubbleIndexList.Count > 0)
                {
                    _bubbleIndexList.Clear();
                }
            }
        }

        public CityRealAiEventPointInfo CheckExistCommodityBubble(int bubbleType)
        {
            if (Seeker == null)
            {
                return null;
            }

            if (!Seeker.aiPath.isStopped)
            {
                return null;
            }

            if (EventDispatch.PointInfo == null || EventDispatch.PointInfo.Owner == null)
            {
                return null;
            }

            if (!CityRealAiManager.GetInstance().HudMgr || !CityRealAiManager.GetInstance().HudMgr.IsExistCommodityHud(Uid, bubbleType, true))
            {
                return null;
            }

            var eventPoint = EventDispatch.PointInfo;

            return eventPoint;
        }

        public void UpdateCommodityHudPerformer(int performerUid)
        {
            CityRealAiManager.GetInstance().HudMgr.OnUpdateComodityPerformer(Uid, performerUid);
        }

        private bool CheckConditionEventList()
        {
            if (_curConditionIndexList != null && _curConditionIndexList.Count > 0)
            {
                InitWaitCondition();
                
                for (int i = 0; i < _curConditionIndexList.Count; i++)
                {
                    var conditionIndex = _curConditionIndexList[i];
                    var config = RoleConfig.condition_event_array[conditionIndex];
                    var factorType = RoleConfig.condition_type[conditionIndex];
                    if ((int)factorType.y == (int)CityRealNpcFocusType.Room)
                    {
                        var conditionPointInfo = _containerMgr.GetEventPointInfo(Uid, (int) config.x, CityRealEventPointState.Wait, CityRealEventPointState.Work);
                        if (conditionPointInfo == null) // 关注事件为空，则跳过。
                        {
                            continue;
                        }
                    }
                    else if ((int)factorType.y == (int)CityRealNpcFocusType.Goods)
                    {
                        if (EventDispatch.PointInfo == null || EventDispatch.PointInfo.Owner == null)
                        {
                            continue;
                        }
                        
                        var conditionPointInfo = EventDispatch.PointInfo.Owner.GetEventPoint(Uid, (int)config.x, CityRealEventPointState.Wait, CityRealEventPointState.Work);
                        if (conditionPointInfo == null) // 关注事件为空，则跳过。
                        {
                            continue;
                        }
                    }
                    
                    if (TreeType == CityRealEventTreeType.RepowerEventTree)
                    {
                        bool can = CheckPower((ConditionType)config.y, (int)config.z);
                        if (can)
                        {
                            _conditionIndexList.Add(conditionIndex);
                        }
                    }
                    else
                    {
                        _conditionIndexList.Add(conditionIndex);
                    }
                }

                if (_conditionIndexList.Count > 0)
                {
                    var totalWeight = 0;
                    for (int i = 0; i < _conditionIndexList.Count; i++)
                    {
                        var index = _conditionIndexList[i];
                        totalWeight += RoleConfig.condition_weight[index];
                    }

                    int conditionIndex = 0;
                    int cursor = 0;
                    int random = Random.Range(0, totalWeight);
                    for (int i = 0; i < _conditionIndexList.Count; i++)
                    {
                        var index = _conditionIndexList[i];
                        cursor += RoleConfig.condition_weight[index];
                        if(cursor > random)
                        {
                            conditionIndex = index;
                            break;
                        }
                    }
                    
                    var config = RoleConfig.condition_event_array[conditionIndex];
                    if (!CheckAndRunRepowerEventTree((ConditionType)config.y, (int)config.z))
                    {
                        return true;
                    }
                    
                    var factorType = RoleConfig.condition_type[conditionIndex];
                    CityRealAiEventPointInfo conditionPointInfo = null;
                    if ((int)factorType.y == (int)CityRealNpcFocusType.Room)
                    {
                        conditionPointInfo = _containerMgr.GetEventPointInfo(Uid, (int) config.x, CityRealEventPointState.Wait, CityRealEventPointState.Work);
                    }
                    else if ((int)factorType.y == (int)CityRealNpcFocusType.Goods)
                    {
                        conditionPointInfo = EventDispatch.PointInfo.Owner.GetEventPoint(Uid, (int)config.x, CityRealEventPointState.Wait, CityRealEventPointState.Work);
                    }

                    CityRealAiEventTreeConfig treeConfig = _cfgMgr.EmptyEventTreeCfg;
                    CityRealAiEventPointInfo pointInfo = null;
                    //类型区分，一为事件二为树
                    if ((ConditionType)config.y == ConditionType.Event)
                    {
                        pointInfo = conditionPointInfo.Owner.GetEventPoint(Uid, (int) config.z, CityRealEventPointState.Idle);
                    }
                    else if ((ConditionType)config.y == ConditionType.Tree)
                    {
                        treeConfig = _cfgMgr.GetAiEventTreeConfig((int) config.z);
                        if (treeConfig.event_tree_id == _cfgMgr.EmptyEventTreeCfg.event_tree_id || treeConfig.event_array.Length <= 0)
                        {
                            return false;
                        }

                        var eventInfo = treeConfig.event_array[0];
                        var eventId = (int) eventInfo.x;
                        pointInfo = conditionPointInfo.Owner.GetEventPoint(Uid, eventId, CityRealEventPointState.Idle);
                    }
                    
                    if (pointInfo != null)
                    {
                        EndEventTree();
                        TreeConfig = treeConfig;
                        TreeState = CityRealEventTreeState.InProgress;
                        TreeType = CityRealEventTreeType.ConditonEventTree;
                        TreeIsInterrupt = false;
                        pointInfo.UpdatePerformer(this);
                        pointInfo.UpdateState(CityRealEventPointState.Move);
                        EventDispatch.UpdatePointInfo(pointInfo);
                        EventDispatch.UpdatePerformerPointInfo(conditionPointInfo);
                        if (pointInfo.EventConfig.parameter == CityRealAiConst.NpcCheckTicketTimeTag)
                        {
                            // 检票进度条
                            CityRealAiManager.GetInstance().HudMgr.OnShowProgressBar(Uid, CityRealAiConst.BubbleProgressBar, CityRealAiConst.CheckTicketTime, _roleObj.transform);
                        }
                        Seeker.InRoomStartMove(Uid, TreeConfig.event_tree_id, pointInfo.PointConfig.Position, pointInfo.PointConfig.Rotate, _containerMgr, pointInfo.EventConfig, ConditionEventMoveEnd, ConditionEventEnd, waitFailedCompleteAction);
                        return true;
                    }
                }
            }

            return false;
        }

        private void InitWaitCondition()
        {
            if (_conditionIndexList == null)
            {
                _conditionIndexList = new List<int>();
            }
            else
            {
                if (_conditionIndexList.Count > 0)
                {
                    _conditionIndexList.Clear();
                }
            }
        }
        
        private bool CheckBreakEventList()
        {
            if (_curBreakIndexList != null && _curBreakIndexList.Count > 0)
            {
                InitWaitBreak();
                for (int i = 0; i < _curBreakIndexList.Count; i++)
                {
                    var breakIndex = _curBreakIndexList[i];
                    var config = RoleConfig.break_event_array[breakIndex];
                    factorType = RoleConfig.break_type[breakIndex];
                    if ((int)factorType.y == (int)CityRealNpcFocusType.Room)
                    {
                        var breakPointInfo = _containerMgr.GetEventPointInfo(Uid, (int) config.x, CityRealEventPointState.Wait, CityRealEventPointState.Work);
                        if (breakPointInfo == null) // 关注事件为空，则跳过。
                        {
                            continue;
                        }
                    }
                    else if ((int)factorType.y == (int)CityRealNpcFocusType.Goods)
                    {
                        if (EventDispatch.PointInfo == null || EventDispatch.PointInfo.Owner == null)
                        {
                            continue;
                        }
                        
                        var breakPointInfo = EventDispatch.PointInfo.Owner.GetEventPoint(Uid, (int)config.x, CityRealEventPointState.Wait, CityRealEventPointState.Work);
                        if (breakPointInfo == null) // 关注事件为空，则跳过。
                        {
                            continue;
                        }
                    }
                    
                    if (TreeType == CityRealEventTreeType.RepowerEventTree)
                    {
                        bool can = CheckPower((ConditionType)config.y, (int)config.z);
                        if (can)
                        {
                            _breakIndexList.Add(breakIndex);
                        }
                    }
                    else
                    {
                        _breakIndexList.Add(breakIndex);
                    }
                }

                if (_breakIndexList.Count > 0)
                {
                    var totalWeight = 0;
                    for (int i = 0; i < _breakIndexList.Count; i++)
                    {
                        var index = _breakIndexList[i];
                        totalWeight += RoleConfig.break_weight[index];
                    }

                    int breakIndex = 0;
                    int cursor = 0;
                    int random = Random.Range(0, totalWeight);
                    for (int i = 0; i < _breakIndexList.Count; i++)
                    {
                        var index = _breakIndexList[i];
                        cursor += RoleConfig.break_weight[index];
                        if(cursor > random)
                        {
                            breakIndex = index;
                            break;
                        }
                    }
                    var config = RoleConfig.break_event_array[breakIndex];
                    if (!CheckAndRunRepowerEventTree((ConditionType)config.y, (int)config.z))
                    {
                        return true;
                    }
                    
                    var factorType = RoleConfig.break_type[breakIndex];
                    CityRealAiEventPointInfo breakPointInfo = null;
                    if ((int)factorType.y == (int)CityRealNpcFocusType.Room)
                    {
                        breakPointInfo = _containerMgr.GetEventPointInfo(Uid, (int) config.x, CityRealEventPointState.Wait, CityRealEventPointState.Work);
                    }
                    else if ((int)factorType.y == (int)CityRealNpcFocusType.Goods)
                    {
                        breakPointInfo = EventDispatch.PointInfo.Owner.GetEventPoint(Uid, (int)config.x, CityRealEventPointState.Wait, CityRealEventPointState.Work);
                    }

                    CityRealAiEventTreeConfig treeConfig = _cfgMgr.EmptyEventTreeCfg;
                    CityRealAiEventPointInfo pointInfo = null;
                    if ((int)config.y == (int)ConditionType.Event)
                    {
                        pointInfo = breakPointInfo.Owner.GetEventPoint(Uid, (int) config.z, CityRealEventPointState.Idle);
                    }
                    else if ((int)config.y == (int)ConditionType.Tree)
                    {
                        treeConfig = _cfgMgr.GetAiEventTreeConfig((int) config.z);
                        if (treeConfig.event_tree_id == _cfgMgr.EmptyEventTreeCfg.event_tree_id || treeConfig.event_array.Length <= 0)
                        {
                            return false;
                        }

                        var eventInfo = treeConfig.event_array[0];
                        var eventId = (int) eventInfo.x;
            
                        pointInfo = breakPointInfo.Owner.GetEventPoint(Uid, eventId, CityRealEventPointState.Idle);
                    }
                    
                    if (pointInfo != null)
                    {
                        EndEventTree();
                        TreeConfig = treeConfig;
                        TreeState = CityRealEventTreeState.InProgress;
                        TreeType = CityRealEventTreeType.BreakEventTree;
                        TreeIsInterrupt = false;
                        pointInfo.UpdatePerformer(this);
                        pointInfo.UpdateState(CityRealEventPointState.Move);
                        EventDispatch.UpdatePointInfo(pointInfo);
                        EventDispatch.UpdatePerformerPointInfo(breakPointInfo);
                        Seeker.InRoomStartMove(Uid, TreeConfig.event_tree_id, pointInfo.PointConfig.Position, pointInfo.PointConfig.Rotate, _containerMgr, pointInfo.EventConfig, BreakEventMoveEnd, BreakEventEnd, waitFailedCompleteAction);
                        return true;
                    }
                }
            }

            return false;
        }
        
        private void InitWaitBreak()
        {
            if (_breakIndexList == null)
            {
                _breakIndexList = new List<int>();
            }
            else
            {
                if (_breakIndexList.Count > 0)
                {
                    _breakIndexList.Clear();
                }
            }
        }

        private bool CheckMoveGoodsEvent()
        {
            if (_curMoveGoodsEventIndexList != null && _curMoveGoodsEventIndexList.Count > 0)
            {
                InitMoveGoodsEvent();
                for (int i = 0; i < _curMoveGoodsEventIndexList.Count; i++)
                {
                    var moveGoodsIndex = _curMoveGoodsEventIndexList[i];
                    var goodsType = RoleConfig.interactive_name_array[moveGoodsIndex];
                    var goodsEventCfg = RoleConfig.interactive_event_array[moveGoodsIndex];
                    var focusType = RoleConfig.interactive_type[moveGoodsIndex];
                    
                    var firstEventId = 0;
                    if ((int)goodsEventCfg.x == (int)ConditionType.Event)
                    {
                        firstEventId = (int)goodsEventCfg.y;
                    }
                    else if ((int)goodsEventCfg.x == (int)ConditionType.Tree)
                    {
                        var treeConfig = _cfgMgr.GetAiEventTreeConfig((int) goodsEventCfg.y);
                        if (treeConfig.event_tree_id == _cfgMgr.EmptyEventTreeCfg.event_tree_id || treeConfig.event_array.Length <= 0)
                        {
                            continue;
                        }
                        var eventInfo = treeConfig.event_array[0];
                        firstEventId = (int) eventInfo.x;
                    }
                    
                    if ((int)focusType.y == (int)CityRealNpcFocusType.Room)
                    {
                        var isExistMoveGoods = _containerMgr.CheckExistMoveGoods(goodsType, Uid, firstEventId, CityRealEventPointState.Idle);
                        if (!isExistMoveGoods)
                        {
                            continue;
                        }
                    }
                    else if ((int)focusType.y == (int)CityRealNpcFocusType.Goods)
                    {
                        if (EventDispatch.PointInfo == null || EventDispatch.PointInfo.Owner == null)
                        {
                            continue;
                        }
                        
                        var isExistMoveGoods = EventDispatch.PointInfo.Owner.CheckExistMoveGoods(goodsType, Uid, firstEventId, CityRealEventPointState.Idle);
                        if (!isExistMoveGoods) // 关注事件为空，则跳过。
                        {
                            continue;
                        }
                    }
                    
                    if (TreeType == CityRealEventTreeType.RepowerEventTree)
                    {
                        bool can = CheckPower((ConditionType)goodsEventCfg.x, (int)goodsEventCfg.y);
                        if (can)
                        {
                            _moveGoodsEventIndexList.Add(moveGoodsIndex);
                        }
                    }
                    else
                    {
                        _moveGoodsEventIndexList.Add(moveGoodsIndex);
                    }
                }

                if (_moveGoodsEventIndexList.Count > 0)
                {
                    var totalWeight = 0;
                    for (int i = 0; i < _moveGoodsEventIndexList.Count; i++)
                    {
                        var index = _moveGoodsEventIndexList[i];
                        totalWeight += RoleConfig.interactive_weight[index];
                    }

                    int randomIndex = 0;
                    int cursor = 0;
                    int random = Random.Range(0, totalWeight);
                    for (int i = 0; i < _moveGoodsEventIndexList.Count; i++)
                    {
                        var index = _moveGoodsEventIndexList[i];
                        cursor += RoleConfig.interactive_weight[index];
                        if(cursor > random)
                        {
                            randomIndex = index;
                            break;
                        }
                    }

                    var config = RoleConfig.interactive_event_array[randomIndex];
                    if (!CheckAndRunRepowerEventTree((ConditionType)config.x, (int)config.y))
                    {
                        return true;
                    }

                    CityRealAiEventTreeConfig treeConfig = _cfgMgr.EmptyEventTreeCfg;
                    var firstEventId = 0;
                    if ((int)config.x == (int)ConditionType.Event)
                    {
                        firstEventId = (int)config.y;
                    }
                    else if ((int)config.x == (int)ConditionType.Tree)
                    {
                        treeConfig = _cfgMgr.GetAiEventTreeConfig((int) config.y);
                        if (treeConfig.event_tree_id == _cfgMgr.EmptyEventTreeCfg.event_tree_id || treeConfig.event_array.Length <= 0)
                        {
                            return false;
                        }
                        var eventInfo = treeConfig.event_array[0];
                        firstEventId = (int) eventInfo.x;
                    }
                    
                    CityRealAiEventPointInfo pointInfo = null;
                    var focusType = RoleConfig.interactive_type[randomIndex];
                    var goodsType = RoleConfig.interactive_name_array[randomIndex];
                    if ((int)focusType.y == (int)CityRealNpcFocusType.Room)
                    {
                        pointInfo = _containerMgr.GetEventPointInfo(Uid, firstEventId, CityRealEventPointState.Idle, goodsType);
                    }
                    else if ((int)focusType.y == (int)CityRealNpcFocusType.Goods)
                    {
                        pointInfo = EventDispatch.PointInfo.Owner.GetEventPoint(Uid, firstEventId, CityRealEventPointState.Idle);
                    }
                    
                    if (pointInfo == null)
                    {
                        return false;
                    }
                    
                    EndEventTree();
                    TreeState = CityRealEventTreeState.InProgress;
                    TreeType = CityRealEventTreeType.MoveGoodsTriggerEventTree;
                    TreeConfig = treeConfig;
                    TreeIsInterrupt = TreeConfig.is_interrupt;
                    pointInfo.UpdatePerformer(this);
                    pointInfo.UpdateState(CityRealEventPointState.Move);
                    EventDispatch.UpdatePointInfo(pointInfo);
                    Seeker.InRoomStartMove(Uid, TreeConfig.event_tree_id, pointInfo.PointConfig.Position, pointInfo.PointConfig.Rotate, _containerMgr, pointInfo.EventConfig, eventMoveEndAction, eventEndAction, waitFailedCompleteAction);
                    return true;
                }
            }

            return false;
        }
        
        private void InitMoveGoodsEvent()
        {
            if (_moveGoodsEventIndexList == null)
            {
                _moveGoodsEventIndexList = new List<int>();
            }
            else
            {
                if (_moveGoodsEventIndexList.Count > 0)
                {
                    _moveGoodsEventIndexList.Clear();
                }
            }
        }

        //执行随机的回复体力事件
        private bool ExecuteRandomRepowerEvent(int checkIndex)
        {
            if (RoleConfig.repower_event_tree_array.Length <= 0)
            {
                return false;
            }

            if (checkIndex > RoleConfig.repower_event_tree_array.Length)
            {
                // 恢复体力事件内太多扣除体力的事件，导致很难随机到恢复体力事件，直接摆烂。
                return false;
            }
            
            var randomList = randomConfigList;
            randomList.Clear();
            for (int i = 0; i < RoleConfig.repower_event_tree_array.Length; i++)
            {
                randomList.Add(new RandomConfig()
                {
                    value = i,
                    weight = (int)RoleConfig.repower_event_tree_array[i].z
                });
            }

            var randomCfg = GetRandomValue();

            var repowerCfg = RoleConfig.repower_event_tree_array[randomCfg.value];
            // 警告！！！ 此处策划坚持要在体力检测事件中再做体力检测，可能会导致死循环。
            if (CheckAndRunRepowerEventTree((ConditionType)repowerCfg.x, (int)repowerCfg.y, checkIndex))
            {
                EndEventTree();
                TreeType = CityRealEventTreeType.RepowerEventTree;
                switch ((ConditionType)repowerCfg.x)
                {
                    case ConditionType.Event:
                        var pointInfo = _containerMgr.GetEventPointInfo(Uid, (int)repowerCfg.y, CityRealEventPointState.Idle);
                        if (pointInfo == null)
                        {
                            TryExecuteEventTree();
                        }
                        else
                        {
                            pointInfo.UpdatePerformer(this);
                            EventDispatch.UpdatePointInfo(pointInfo);
                            TreeIsInterrupt = true;
                            StartEvent();
                        }
                        break;
                    case ConditionType.Tree:
                        TreeConfig = _cfgMgr.GetAiEventTreeConfig((int) repowerCfg.y);
                        TreeState = CityRealEventTreeState.WaitMoveRoom;
                        TreeIsInterrupt = TreeConfig.is_interrupt;
                        ExecuteEventTreePosition();
                        break;
                }
            }

            return true;
        }

        private void ConditionEventMoveEnd()
        {
            var performerPointInfo = EventDispatch.PerformerPointInfo;
            if (performerPointInfo.State == CityRealEventPointState.Wait || 
                performerPointInfo.State == CityRealEventPointState.Work)
            {
                Seeker.PlayAni();
                if ((int)performerPointInfo.EventConfig.append_type.x == (int)CityRealNpcEffectTriggerType.StartEvent)
                {
                    OnTriggerEffect();
                }
                performerPointInfo.Performer.PassiveConditionEventMoveEnd();
                EventDispatch.PointInfo.UpdateState(CityRealEventPointState.Work);
            }
            else // 已经不处于等待中，说明有人完成了该事件，则随机新事件。
            {
                EndEventTree();
                TryExecuteEventTree();
            }
        }

        public void PassiveConditionEventMoveEnd()
        { 
            if (EventDispatch.PointInfo.State == CityRealEventPointState.Wait)
            {
                Seeker.PlayAni();
                if ((int)EventDispatch.PointInfo.EventConfig.append_type.x == (int)CityRealNpcEffectTriggerType.StartEvent)
                {
                    OnTriggerEffect();
                }
            }
            EventDispatch.PointInfo.UpdateState(CityRealEventPointState.Work);
        }

        private void ConditionEventEnd()
        {
            var pointInfo = EventDispatch.PointInfo;
            pointInfo.UpdateState(CityRealEventPointState.Idle);
            var performerPointInfo = EventDispatch.PerformerPointInfo;
            if (performerPointInfo.EventConfig.time_type == (int) CityRealEventTimeType.WaitTime)
            {
                performerPointInfo.UpdateState(CityRealEventPointState.Idle);
                performerPointInfo.Performer?.EventEnd();
            }
            EventEnd();
        }

        private void BreakEventMoveEnd()
        {
            var performerPointInfo = EventDispatch.PerformerPointInfo;
            if (performerPointInfo.State == CityRealEventPointState.Work ||
                performerPointInfo.State == CityRealEventPointState.Wait)
            {
                Seeker.PlayAni();
                if ((int)performerPointInfo.EventConfig.append_type.x == (int)CityRealNpcEffectTriggerType.StartEvent)
                {
                    OnTriggerEffect();
                }
                performerPointInfo.Performer.PassiveBreakEventEnd();
                EventDispatch.PointInfo.UpdateState(CityRealEventPointState.Work);
            }
            else // 已经不处于等待中，说明有人完成了该事件，则随机新事件。
            {
                EndEventTree();
                TryExecuteEventTree();
            }
        }

        private void BreakEventEnd()
        {
            EventEnd();
        }

        public void PassiveBreakEventEnd()
        {
            if (EventDispatch.PointInfo != null && !string.IsNullOrEmpty(EventDispatch.PointInfo.PointConfig.GoodsTriggerName))
            {
                EventDispatch.PointInfo.Owner.ResetTriggerAnimation();
            }
            var eventInfo = TreeConfig.event_array[_curEventIndex];
            var breakType = (int) eventInfo.y;
            if (breakType == (int) CityRealEventBreakType.Branch)
            {
                EndEventTree();
                var treeId = (int) eventInfo.z;             
                if (CheckAndRunRepowerEventTree(ConditionType.Tree, treeId))
                {
                    TreeConfig = _cfgMgr.GetAiEventTreeConfig(treeId);
                    TreeIsInterrupt = TreeConfig.is_interrupt;
                    TreeState = CityRealEventTreeState.WaitMoveRoom;
                    ExecuteEventTreePosition();
                }
            }
            else if (breakType == (int) CityRealEventBreakType.Failed)
            {
                EndEventTree();
                TreeState = CityRealEventTreeState.ExecuteFailed;
                TryExecuteEventTree();
            }
            else if (breakType == (int) CityRealEventBreakType.Replace)
            {
                var replaceEventId = (int) eventInfo.z;
                if (CheckAndRunRepowerEventTree(ConditionType.Event, replaceEventId))
                {
                    var pointState = CityRealEventPointState.Idle;
                    CityRealAiEventPointInfo replacePointInfo = null;
                    if (EventDispatch.PointInfo != null)
                    {
                        replacePointInfo = EventDispatch.PointInfo.Owner.GetEventPoint(Uid, replaceEventId, pointState);
                    }
                    if (replacePointInfo == null) // 下个事件交互点可能发生了变化
                    {
                        replacePointInfo = _containerMgr.GetEventPointInfo(Uid, replaceEventId, pointState);
                    }

                    if (replacePointInfo == null)
                    {
                        EndEventTree();
                        TreeState = CityRealEventTreeState.ExecuteFailed;
                        TryExecuteEventTree();
                    }
                    else
                    {
                        EventDispatch.PointInfo?.Reset();
                        EventDispatch.Reset();
                        replacePointInfo.UpdatePerformer(this);
                        replacePointInfo.UpdateState(CityRealEventPointState.Move);
                        EventDispatch.UpdatePointInfo(replacePointInfo);
                        Seeker.InRoomStartMove(Uid, TreeConfig.event_tree_id, replacePointInfo.PointConfig.Position, replacePointInfo.PointConfig.Rotate, _containerMgr, replacePointInfo.EventConfig, eventMoveEndAction, eventEndAction, waitFailedCompleteAction);
                    }
                }
            }
            else if (breakType == (int)CityRealEventBreakType.Jump)
            {
                NextEvent();
            }
            else
            {
                Debug.LogErrorFormat(LogModule.CityAI, LogLevelType.Develop, "Uid = {0} treeId = {1} eventId = {2} 未实现的结算类型 type = {3}", Uid, TreeConfig.event_tree_id, eventInfo.x, eventInfo.y);
            }
        }

        public void RemoveFromContainer()
        {
            EndEventTree();
            // 从排队队列中移除
            if (_moveToRoom != null)
            {
                _moveToRoom.TriggerWaitQueueLeave(this);
            }
            
            _containerMgr.RemoveNpcCtrl(RoleId, Uid);

            if (_containerMgr is CityRealAiRoomManager || _containerMgr is CityRealAiWallManager)
            {
                // 房间 / 城墙
                CityRealAiRoomManager roomMgr = _containerMgr as CityRealAiRoomManager;
                CityRealAiAreaManager areaMgr = CityRealAiManager.GetInstance().GetArea(roomMgr.AreaId);
                if (areaMgr != null)
                {
                    areaMgr.RemoveNpcCtrlFromAllDic(this);
                }
            }
        }

        public override void Dispose()
        {
            CityRealAiManager.GetInstance().HudMgr.OnHideHud(Uid);
            CityRealAiManager.GetInstance().HudMgr.OnHideSkillHud(Uid);
            CityRealAiManager.GetInstance().HudMgr.OnHideProgressBar(Uid);
            CityRealAiManager.GetInstance().HudMgr.OnHideCommodity(Uid);
            CityRealAiManager.GetInstance().HudMgr.OnHideEffect(Uid);
            
            if (Timers.inst.Exists(_onDelatyStart))
            {
                Timers.inst.Remove(_onDelatyStart);
            }
            if (Timers.inst.Exists(_npcLightAnimation))
            {
                Timers.inst.Remove(_npcLightAnimation);
            }
            EndEventTree();
            if (AniEventController != null)
            {
                AniEventController.OnTriggerFixed -= _onTriggerFixed;
                AniEventController.OnBindBone -= _onBindBone;
                AniEventController.OnAddItem -= _onAddItem;
                AniEventController.OnGetItem -= _onGetItem;
                AniEventController.OnPutDownItem -= _onPutDownItem;
                AniEventController.OnDeleteItem -= _onDeleteItem;
                AniEventController.OnShowBubble -= _onShowBubble;
                AniEventController.OnHideBubble -= _onHideBubble;
                AniEventController.OnTriggerEffect -= _onTriggerEffect;
                AniEventController = null;
                _onTriggerFixed = null;
                _onBindBone = null;
                _onAddItem = null;
                _onGetItem = null;
                _onPutDownItem = null;
                _onDeleteItem = null;
                _onShowBubble = null;
                _onHideBubble = null;
            }

            if (_roleObj != null)
            {
                CityRealAiManager.GetInstance().Push(ModelPath, _roleObj);
                _roleObj = null;
            }
            if (Seeker != null)
            {
                _npcRoot = null;
                HandRoot = null;
                Seeker.OnReset();
                Object.Destroy(Seeker.gameObject);
                Seeker = null;
            }
            if (!string.IsNullOrEmpty(HandObjPath) && HandObj)
            {
                CityRealAiManager.GetInstance().Push(HandObjPath, HandObj);
                HandObjPath = null;
                HandObj = null;
            }
            if (Timers.inst.Exists(_onDestroyTriggerEffect))
            {
                Timers.inst.Remove(_onDestroyTriggerEffect);
            }
            if (TriggerEffectObj != null)
            {
                CityRealAiManager.GetInstance().Push(TriggerEffectObjPath, TriggerEffectObj);
                TriggerEffectObj = null;
            }

            if (SupperNpcEffectObj != null)
            {
                CityRealAiManager.GetInstance().Push(CityRealAiConst.SupperNpcEffectName, SupperNpcEffectObj);
                SupperNpcEffectObj = null;
            }

            _isInPlayTriggerEffect = false;

            RoleConfig = _cfgMgr.EmptyRoleCfg;
            _cacheWaitEventTreeConfig = _cfgMgr.EmptyEventTreeCfg;
            if (_curBubbleIndexList != null)
            {
                _curBubbleIndexList.Clear();
                _curBubbleIndexList = null;
            }
            if (_curConditionIndexList != null)
            {
                _curConditionIndexList.Clear();
                _curConditionIndexList = null;
            }

            if (_curBreakIndexList != null)
            {
                _curBreakIndexList.Clear();
                _curBreakIndexList = null;
            }

            if (_curMoveGoodsEventIndexList != null)
            {
                _curMoveGoodsEventIndexList.Clear();
                _curMoveGoodsEventIndexList = null;
            }

            if (_bubbleIndexList != null)
            {
                _bubbleIndexList.Clear();
                _bubbleIndexList = null;
            }

            if (_conditionIndexList != null)
            {
                _conditionIndexList.Clear();
                _conditionIndexList = null;
            }

            if (_breakIndexList != null)
            {
                _breakIndexList.Clear();
                _breakIndexList = null;
            }

            if (_moveGoodsEventIndexList != null)
            {
                _moveGoodsEventIndexList.Clear();
                _moveGoodsEventIndexList = null;
            }

            if (_tweener != null)
            {
                _tweener.Kill();
                _tweener = null;
            }


            IsLoadComplete = false;
            model = null;
            _roleObj = null;
        }
        
        public struct RandomConfig
        {
            //返回值（不一定是int，float、枚举、类、结构体都可以）
            public int value;
            //随机权重
            public int weight;
        }

        protected List<RandomConfig> randomConfigList = new List<RandomConfig>(32);
        private Vector2 factorType;


        //---------

        protected RandomConfig GetRandomValue()
        {
            var list = randomConfigList;

            //累加结算总权重
            int totalWeight = 0;
            foreach (var config in list) 
                totalWeight += config.weight;

            //在0~total范围内随机
            int cursor = 0;
            int random = Random.Range(0,totalWeight);
            foreach(var item in list)
            {
                //累加当前权重
                cursor += item.weight;
                //判断随机数
                if(cursor > random)
                {
                    return item;
                }
            }
            return list[0];
        }

        //检查事件执行的体力消耗是否足够
        private bool CheckPower(ConditionType type, int id)
        {
            int totalCost = 0;
            //事件查事件需要的体力
            if (type == ConditionType.Event)
            {
                var cfg = _cfgMgr.GetAiEventConfig(id);
                totalCost = cfg.power_change;
            }
            //树检查里面的每个事件
            else if (type == ConditionType.Tree)
            {
                var cfg = _cfgMgr.GetAiEventTreeConfig(id);
                //检查整个树里面所有的事件体力消耗
                var eventList = cfg.event_array;
                for (int i = 0; i < eventList.Length; i++)
                {
                    var itemCfg = eventList[i];
                    int eventId = (int)itemCfg.x;
                    var eventCfg = _cfgMgr.GetAiEventConfig(eventId);
                    if (eventCfg.event_id != _cfgMgr.EmptyEventCfg.event_id)
                    {
                        totalCost += eventCfg.power_change;
                    }
                }
            }
            //如果体力不够则执行回复体力的池子
            //如果小于0则是消耗
            if (CurrentPower + totalCost >= 0)
            {
                return true;
            }
            
            return false;
        }
        //npc从事件目标位置拿取道具
        private void OnBindBone(int skeletonPoint)
        {
            var cfg = _cfgMgr.GetBonePathConfig(skeletonPoint);
            if (cfg.id == _cfgMgr.EmptyBonePathCfg.id || string.IsNullOrEmpty(cfg.bone_path))
            {
                return;
            }

            string bonePath = cfg.bone_path;
            if (model)
            {
                bonePath = bonePath.Substring(bonePath.LastIndexOf("/") + 1);
            }

            Transform bone = null;
            if(string.Equals(bonePath, "Root"))
            {
                bone = _roleObj.transform;
            }
            else
            {
                bone =  _roleObj.transform.Find(bonePath);
            }
            if (bone)
            {
                HandRoot = bone;
            }
        }
        //在npc身上生成道具
        private void OnAddItem()
        {
            if (EventDispatch.PointInfo == null)
            {
                return;
            }
            
            // Debug.LogFormat(LogModule.CityAI, "EventId = {0} 触发OnAddItem事件", LogLevelType.Develop, EventDispatch.PointInfo.EventId);
            CheckBonePath();
            //直接生成道具在骨骼点目标节点下
            if (HandRoot == null)
            {
                return;
            }

            if (HandObj)
            {
                return;
            }
            //获取事件中对应的交互物名称
            string interactive = EventDispatch.PointInfo.EventConfig.interactive;
            if (!string.IsNullOrEmpty(interactive))
            {
                LoadInteractive(interactive);
            }
        }
        //npc从事件目标位置拿取道具
        //TODO:后续加入对象池
        private void OnGetItem()
        {
            CheckBonePath();
            if (HandRoot == null)
            {
                return;
            }

            if (HandObj)
            {
                return;
            }
            
            var pointInfo = EventDispatch.PointInfo;
            if (pointInfo != null && pointInfo.Owner != null)
            {
                // Debug.LogFormat(LogModule.CityAI, "EventId = {0} 触发OnGetItem事件", LogLevelType.Develop, EventDispatch.PointInfo.EventId);
                var moveGoodsObj = pointInfo.Owner.GetMoveGoods(pointInfo.PointConfig.MoveGoodsName);
                if (moveGoodsObj != null)
                {
                    HandObjPath = null;
                    HandObj = moveGoodsObj;
                    HandObj.SetParent(HandRoot, true);
                    HandObj.transform.localPosition = Vector3.zero;
                    HandObj.transform.localEulerAngles = Vector3.zero;
                    var goodsRotateMono = HandObj.GetComponentInChildren<CityRealMoveGoodsMono>();
                    if (goodsRotateMono != null)
                    {
                        goodsRotateMono.ChangeNodeRotate(false, pointInfo.EventConfig.bind_positionoffset_id);
                    }
                }
            }

            if (HandObj == null) // 策划需求，如果交互物里Get不到，就Add一个。
            {
                OnAddItem();
            }
        }
        //npc从身上放下道具
        private void OnPutDownItem()
        {
            if (HandObj)
            {
                var pointInfo = EventDispatch.PointInfo;
                if (pointInfo != null && pointInfo.Owner != null)
                {                
                    // Debug.LogFormat(LogModule.CityAI, "EventId = {0} 触发OnPutDownItem事件", LogLevelType.Develop, pointInfo.EventId);
                    var pointCfg = pointInfo.PointConfig;
                    var moveGoodsIndex = pointInfo.Owner.OnUpdateMoveGoods(pointCfg.MoveGoodsName, HandObj);
                    if (moveGoodsIndex < 0) // 没有多余的空位可以放置了
                    {
                        Object.Destroy(HandObj);
                    }
                    else
                    {
                        //先将物体父节点至于房间内
                        HandObj.SetParent(_containerMgr.RoomRootTran, true);
                        HandObj.transform.localPosition = pointCfg.MoveGoodsPosList[moveGoodsIndex];
                        HandObj.transform.localEulerAngles = pointCfg.MoveGoodsRotList[moveGoodsIndex];
                        var goodsRotateMono = HandObj.GetComponentInChildren<CityRealMoveGoodsMono>();
                        if (goodsRotateMono != null)
                        {
                            goodsRotateMono.ChangeNodeRotate(true);
                        }
                    }
                }
                else
                {
                    Object.Destroy(HandObj);
                }
                HandObj = null;
            }
        }
        //移除npc身上的道具
        //TODO:后续加入对象池
        private void OnDeleteItem()
        {
            // if (EventDispatch.PointInfo != null)
            // {            
            //     Debug.LogFormat(LogModule.CityAI, "EventId = {0} 触发OnDeleteItem事件", LogLevelType.Develop, EventDispatch.PointInfo.EventId);
            // }
            if (!string.IsNullOrEmpty(HandObjPath) && HandObj)
            {
                CityRealAiManager.GetInstance().Push(HandObjPath, HandObj);
                HandObjPath = null;
                HandObj = null;
            }
        }
        //触发固定道具的动画表演
        private void OnTriggerFixed()
        {
            if (EventDispatch.PointInfo == null || 
                EventDispatch.PointInfo.Owner == null || 
                EventDispatch.PointInfo.PointConfig.eventId <= 0 ||
                string.IsNullOrEmpty(EventDispatch.PointInfo.PointConfig.GoodsTriggerName))
            {
                return;
            }
            
            // Debug.LogFormat(LogModule.CityAI, "EventId = {0} TriggerName = {1} 触发OnTriggerFixed事件", LogLevelType.Develop, EventDispatch.PointInfo.EventId, EventDispatch.PointInfo.PointConfig.GoodsTriggerName);
            EventDispatch.PointInfo.Owner.TriggerAnimation(EventDispatch.PointInfo.PointConfig.GoodsTriggerName);
        }
        
        //检查骨骼节点
        private void CheckBonePath()
        {
            if (EventDispatch.PointInfo == null || EventDispatch.PointInfo.EventConfig.event_id == _cfgMgr.EmptyEventCfg.event_id)
            {
                return;
            }
            
            int pathId = EventDispatch.PointInfo.EventConfig.bones_bind_interactive;
            if (pathId <= 0)
            {
                return;
            }
            
            var cfg = _cfgMgr.GetBonePathConfig(pathId);
            if (cfg.id == _cfgMgr.EmptyBonePathCfg.id || string.IsNullOrEmpty(cfg.bone_path))
            {
                return;
            }
            string bonePath = cfg.bone_path;
            if (model)
            {
                bonePath = bonePath.Substring(bonePath.LastIndexOf("/") + 1);
            }
            Transform bone = null;
            if (string.Equals(bonePath, "Root"))
            {
                bone = _roleObj.transform;
            }
            else
            {
                bone =  _roleObj.transform.Find(bonePath);
            }
            if (bone)
            {
                HandRoot = bone;
            }
            else
            {
                Debug.LogErrorFormat(LogModule.CityAI, LogLevelType.Develop, "bonePath = {0}, cfg.BonePath = {1}, model = {2}", bonePath, cfg.bone_path, _roleObj);
            }
            
        }

        private void OnShowBubble()
        {
            if (!IsAlive)
            {
                return;
            }
            
            if (_isPause)
            {
                return;
            }

            if (_containerMgr is CityRealAiRoomManager roomMgr)
            {
                // if (roomMgr.IsInState(CityRealRoomState.Upgrade))
                // {
                //     return;
                // }

                if (!roomMgr.rendererNpcEnabled)
                {
                    return;
                }
            }

            if (model && !model.rendererEnabled) // 未渲染模式下，不触发hud
            {
                return;
            }
            
            var pointInfo = EventDispatch.PointInfo;
            if (pointInfo == null)
            {
                return;
            }

            if (string.IsNullOrEmpty(pointInfo.EventConfig.bubble) || pointInfo.EventConfig.bones_bind_bubble <= 0)
            {
                return;
            }
            
            if (pointInfo.BubbleIndex < CityRealAiConst.HudTriggerMaxNum)
            {
                // Debug.LogFormat(LogModule.CityAI, "EventId = {0} 触发OnShowBubble事件", LogLevelType.Develop, pointInfo.EventId);
                pointInfo.UpdateBubbleIndex();
                var eventConfig = EventDispatch.PointInfo.EventConfig;
                // 动画事件触发气泡
                if (eventConfig.bubble_start_type == (int)CityRealEventBubbleStartType.AnimationEvent)
                {
                    ShowEventBubble(ref eventConfig);
                }
            }
            else
            {
#if UNITY_EDITOR && ENABLE_CITY_AI_PROFILER
                Debug.LogFormat(LogModule.CityAI, "EventId = {0} 触发OnShowBubble事件 未满足触发次数，触发失败", LogLevelType.Develop, pointInfo.EventId);
#endif
            }
        }

        // 显示事件气泡
        protected void ShowEventBubble(ref CityRealAiEventConfig eventConfig)
        {
            switch ((CityRealEventBubbleHudType)eventConfig.bubble_hud_type)
            {
                case CityRealEventBubbleHudType.Common:
                    {
                        // 普通气泡
                        if ((int)eventConfig.bubble_type.x == 2) // 时间到了自动消失
                        {
                            CityRealAiManager.GetInstance().HudMgr.OnShowHud(Uid, _roleObj.transform, eventConfig.bubble,
                                eventConfig.bubble_type.y, eventConfig.bones_bind_bubble, eventConfig.event_id);
                        }
                        else
                        {
                            CityRealAiManager.GetInstance().HudMgr.OnShowHud(Uid, _roleObj.transform, eventConfig.bubble,
                                -1, eventConfig.bones_bind_bubble, eventConfig.event_id);
                        }
                    }
                    break;
            
                case CityRealEventBubbleHudType.Staff:
                    {
                        // 雇员气泡
                        CityRealAiManager.GetInstance().HudMgr.OnShowStaff(Uid, eventConfig.bubble, _roleObj.transform,
                            this.staffId, CityRealAiConst.DefaultBubbleBone);
                    }
                    break;
            
                case CityRealEventBubbleHudType.Dialogue:
                    {
                        // 对话气泡
                        CityRealAiManager.GetInstance().HudMgr.OnShowDialogue(Uid, CityRealAiConst.BubbleDialogue, _roleObj.transform,
                            areaId, eventConfig.bubble_type.y, CityRealAiConst.DefaultBubbleBone);
                    }
                    break;
            }
        }

        private void OnHideBubble()
        {
            var pointInfo = EventDispatch.PointInfo;
            if (pointInfo == null)
            {
                return;
            }
            
            // Debug.LogFormat(LogModule.CityAI, "EventId = {0} 触发OnHideBubble事件", LogLevelType.Develop, pointInfo.EventId);
            CityRealAiManager.GetInstance().HudMgr.OnHideHud(Uid);
        }

        private void OnTriggerEffect()
        {
            if (!IsAlive)
            {
                return;
            }

            if (_isPause)
            {
                return;
            }
            
            // if (_containerMgr is CityRealAiRoomManager roomMgr)
            // {
            //     if (roomMgr.IsInState(CityRealRoomState.Upgrade))
            //     {
            //         return;
            //     }
            // }

            if (model && !model.rendererEnabled) // 未渲染模式下，不触发hud
            {
                return;
            }
            
            var pointInfo = EventDispatch.PointInfo;
            if (pointInfo == null)
            {
                return;
            }

            if (string.IsNullOrEmpty(pointInfo.EventConfig.append) || pointInfo.EventConfig.bones_bind_append <= 0)
            {
                return;
            }

            if (_isInPlayTriggerEffect) // 已经有特效在播放了
            {
                return;
            }

            LoadTriggerEffect(pointInfo.EventConfig.append_type.y, pointInfo.EventConfig.append, pointInfo.EventConfig.bones_bind_append);
        }
        
        public void LoadTriggerEffect(float effectLength, string triggerEffect, int triggerEffectBonesId)
        {
            var bonesCfg = _cfgMgr.GetBonePathConfig(triggerEffectBonesId);
            if (bonesCfg.id == _cfgMgr.EmptyBonePathCfg.id || string.IsNullOrEmpty(bonesCfg.bone_path))
            {
                return;
            }
            
            string bonePath = bonesCfg.bone_path;
            if (model)
            {
                bonePath = bonePath.Substring(bonePath.LastIndexOf("/") + 1);
            }

            Transform bone = null;
            if (string.Equals(bonePath, "Root"))
            {
                bone = _roleObj.transform;
            }
            else
            {
                bone = _roleObj.transform.Find(bonePath);
            }
            if (bone == null)
            {
                return;
            }

            _isInPlayTriggerEffect = true;
            
            TriggerEffectObjPath = string.Format(CityRealAiConst.TriggerEffectPath, triggerEffect);
            CityRealAiManager.GetInstance().Pop(TriggerEffectObjPath, asset =>
            {
                TriggerEffectObj = asset;
                TriggerEffectObj.SetParent(bone, true);
                TriggerEffectObj.transform.localPosition = Vector3.zero;
                TriggerEffectObj.transform.localEulerAngles = Vector3.zero;
#if UNITY_EDITOR
                TriggerEffectObj.name = $"AI事件触发特效 = {triggerEffect}";
#endif
                Timers.inst.Add(effectLength, 1, _onDestroyTriggerEffect);
            });
        }

        private void OnDestroyTriggerEffect(object o)
        {
            if (TriggerEffectObj != null)
            {
                CityRealAiManager.GetInstance().Push(TriggerEffectObjPath, TriggerEffectObj);
                TriggerEffectObj = null;
            }
            _isInPlayTriggerEffect = false;
        }

        public void ResetTimestamp()
        {
            _timeStamp = 0;
        }
    }
}
